From a9a87f39e5d9da407ce9531ae50287a20d20e0dc Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Fri, 4 Nov 2022 09:57:20 -0400 Subject: [PATCH] chore: upgrade deps --- .../btcsuite/btcd/btcec/v2/btcec.go | 15 + .../btcsuite/btcd/btcec/v2/curve.go | 52 + .../btcsuite/btcd/btcec/v2/error.go | 5 + vendor/github.com/cheekybits/genny/.gitignore | 26 - .../github.com/cheekybits/genny/.travis.yml | 6 - vendor/github.com/cheekybits/genny/README.md | 245 - vendor/github.com/cheekybits/genny/doc.go | 2 - .../cheekybits/genny/generic/doc.go | 2 - .../cheekybits/genny/generic/generic.go | 13 - vendor/github.com/cheekybits/genny/main.go | 154 - .../cheekybits/genny/out/lazy_file.go | 38 - .../cheekybits/genny/parse/builtins.go | 41 - .../github.com/cheekybits/genny/parse/doc.go | 14 - .../cheekybits/genny/parse/errors.go | 47 - .../cheekybits/genny/parse/parse.go | 298 - .../cheekybits/genny/parse/typesets.go | 89 - .../coreos/go-systemd/v22/dbus/dbus.go | 5 + .../coreos/go-systemd/v22/dbus/methods.go | 34 + .../secp256k1/v4/compressedbytepoints.go | 11 +- .../decred/dcrd/dcrec/secp256k1/v4/curve.go | 591 +- .../decred/dcrd/dcrec/secp256k1/v4/doc.go | 39 +- .../dcrd/dcrec/secp256k1/v4/ecdsa/doc.go | 4 +- .../dcrd/dcrec/secp256k1/v4/ecdsa/error.go | 20 +- .../dcrec/secp256k1/v4/ecdsa/signature.go | 247 +- .../dcrec/secp256k1/v4/ellipticadaptor.go | 6 +- .../decred/dcrd/dcrec/secp256k1/v4/field.go | 193 +- .../dcrd/dcrec/secp256k1/v4/genstatics.go | 196 - .../dcrec/secp256k1/v4/loadprecomputed.go | 32 +- .../dcrd/dcrec/secp256k1/v4/modnscalar.go | 17 +- .../decred/dcrd/dcrec/secp256k1/v4/privkey.go | 30 +- .../decred/dcrd/dcrec/secp256k1/v4/pubkey.go | 19 +- vendor/github.com/docker/go-units/size.go | 70 +- vendor/github.com/gogo/protobuf/io/full.go | 102 - vendor/github.com/gogo/protobuf/io/io.go | 70 - vendor/github.com/gogo/protobuf/io/uint32.go | 138 - vendor/github.com/gogo/protobuf/io/varint.go | 133 - .../github.com/golang/mock/mockgen/mockgen.go | 701 + .../golang/mock/mockgen/model/model.go | 495 + .../github.com/golang/mock/mockgen/parse.go | 644 + .../github.com/golang/mock/mockgen/reflect.go | 256 + .../golang/mock/mockgen/version.1.11.go | 26 + .../golang/mock/mockgen/version.1.12.go | 35 + vendor/github.com/ipfs/go-cid/cid.go | 28 +- vendor/github.com/ipfs/go-cid/cid_fuzz.go | 1 - vendor/github.com/ipfs/go-cid/version.json | 2 +- .../github.com/ipfs/go-datastore/.gitignore | 1 - vendor/github.com/ipfs/go-datastore/LICENSE | 21 - vendor/github.com/ipfs/go-datastore/README.md | 47 - .../github.com/ipfs/go-datastore/basic_ds.go | 304 - vendor/github.com/ipfs/go-datastore/batch.go | 53 - .../github.com/ipfs/go-datastore/datastore.go | 252 - vendor/github.com/ipfs/go-datastore/key.go | 309 - .../ipfs/go-datastore/query/filter.go | 102 - .../ipfs/go-datastore/query/order.go | 94 - .../ipfs/go-datastore/query/query.go | 426 - .../ipfs/go-datastore/query/query_impl.go | 158 - .../github.com/ipfs/go-datastore/version.json | 3 - vendor/github.com/ipfs/go-ds-sql/LICENSE | 21 - vendor/github.com/ipfs/go-ds-sql/README.md | 130 - vendor/github.com/ipfs/go-ds-sql/batching.go | 65 - vendor/github.com/ipfs/go-ds-sql/dstore.go | 204 - vendor/github.com/ipfs/go-ds-sql/package.json | 30 - vendor/github.com/ipfs/go-ds-sql/txn.go | 122 - vendor/github.com/ipfs/go-ds-sql/version.json | 3 - .../github.com/jbenet/goprocess/.travis.yml | 9 - vendor/github.com/jbenet/goprocess/LICENSE | 21 - vendor/github.com/jbenet/goprocess/README.md | 132 - .../github.com/jbenet/goprocess/background.go | 33 - .../github.com/jbenet/goprocess/goprocess.go | 263 - .../github.com/jbenet/goprocess/impl-mutex.go | 299 - vendor/github.com/jbenet/goprocess/link.go | 128 - .../github.com/jbenet/goprocess/package.json | 14 - .../github.com/klauspost/compress/.gitignore | 7 + .../github.com/klauspost/compress/README.md | 77 + .../klauspost/compress/huff0/autogen.go | 5 - .../klauspost/compress/huff0/bitreader.go | 10 - .../klauspost/compress/huff0/bitwriter.go | 115 - .../klauspost/compress/huff0/bytereader.go | 10 - .../klauspost/compress/huff0/compress.go | 1 + .../klauspost/compress/huff0/decompress.go | 149 +- .../compress/huff0/decompress_8b_amd64.s | 488 - .../compress/huff0/decompress_8b_amd64.s.in | 197 - .../compress/huff0/decompress_amd64.go | 179 +- .../compress/huff0/decompress_amd64.s | 1174 +- .../compress/huff0/decompress_amd64.s.in | 195 - .../compress/huff0/decompress_generic.go | 120 +- .../compress/internal/cpuinfo/cpuinfo.go | 34 + .../internal/cpuinfo/cpuinfo_amd64.go | 11 + .../compress/internal/cpuinfo/cpuinfo_amd64.s | 36 + .../compress/internal/snapref/encode_other.go | 6 +- .../klauspost/compress/zstd/README.md | 56 +- .../klauspost/compress/zstd/bitreader.go | 7 - .../klauspost/compress/zstd/bitwriter.go | 76 - .../klauspost/compress/zstd/blockdec.go | 72 +- .../klauspost/compress/zstd/bytebuf.go | 20 +- .../klauspost/compress/zstd/bytereader.go | 6 - .../klauspost/compress/zstd/decoder.go | 143 +- .../compress/zstd/decoder_options.go | 25 +- .../klauspost/compress/zstd/enc_better.go | 31 +- .../klauspost/compress/zstd/enc_dfast.go | 17 +- .../klauspost/compress/zstd/enc_fast.go | 6 +- .../klauspost/compress/zstd/encoder.go | 6 +- .../compress/zstd/encoder_options.go | 2 +- .../klauspost/compress/zstd/framedec.go | 110 +- .../klauspost/compress/zstd/fse_decoder.go | 128 +- .../compress/zstd/fse_decoder_amd64.go | 64 + .../compress/zstd/fse_decoder_amd64.s | 126 + .../compress/zstd/fse_decoder_generic.go | 72 + .../klauspost/compress/zstd/fse_encoder.go | 23 - .../klauspost/compress/zstd/fuzz.go | 11 - .../klauspost/compress/zstd/fuzz_none.go | 11 - .../klauspost/compress/zstd/hash.go | 6 - .../klauspost/compress/zstd/seqdec.go | 260 +- .../klauspost/compress/zstd/seqdec_amd64.go | 378 + .../klauspost/compress/zstd/seqdec_amd64.s | 4099 +++ .../klauspost/compress/zstd/seqdec_generic.go | 237 + .../github.com/klauspost/compress/zstd/zip.go | 59 +- .../klauspost/compress/zstd/zstd.go | 11 - vendor/github.com/klauspost/cpuid/v2/cpuid.go | 143 +- .../klauspost/cpuid/v2/detect_x86.go | 2 +- .../klauspost/cpuid/v2/featureid_string.go | 271 +- .../klauspost/cpuid/v2/os_darwin_arm64.go | 112 +- .../github.com/libp2p/go-eventbus/.travis.yml | 30 - .../github.com/libp2p/go-eventbus/README.md | 25 - .../github.com/libp2p/go-eventbus/codecov.yml | 3 - .../libp2p/go-flow-metrics/.travis.yml | 2 +- .../libp2p/go-flow-metrics/sweeper.go | 16 +- .../github.com/libp2p/go-libp2p-core/LICENSE | 4 - .../libp2p/go-libp2p-core/LICENSE-APACHE | 13 - .../libp2p/go-libp2p-core/LICENSE-MIT | 19 - .../libp2p/go-libp2p-core/event/doc.go | 11 - .../libp2p/go-libp2p-core/test/addrs.go | 42 - .../libp2p/go-libp2p-core/test/crypto.go | 21 - .../libp2p/go-libp2p-core/test/errors.go | 19 - .../libp2p/go-libp2p-core/test/peer.go | 25 - .../libp2p/go-libp2p-peerstore/.gitignore | 2 - .../libp2p/go-libp2p-peerstore/LICENSE | 21 - .../libp2p/go-libp2p-peerstore/README.md | 37 - .../libp2p/go-libp2p-peerstore/codecov.yml | 5 - .../libp2p/go-libp2p-peerstore/pb/Makefile | 12 - .../libp2p/go-libp2p-peerstore/pb/custom.go | 110 - .../go-libp2p-peerstore/pb/pstore.pb.go | 1027 - .../go-libp2p-peerstore/pb/pstore.proto | 40 - .../go-libp2p-peerstore/pstoreds/addr_book.go | 605 - .../pstoreds/addr_book_gc.go | 410 - .../go-libp2p-peerstore/pstoreds/cache.go | 40 - .../pstoreds/cyclic_batch.go | 78 - .../go-libp2p-peerstore/pstoreds/keybook.go | 137 - .../go-libp2p-peerstore/pstoreds/metadata.go | 81 - .../go-libp2p-peerstore/pstoreds/peerstore.go | 191 - .../go-libp2p-peerstore/pstoreds/protobook.go | 196 - .../libp2p/go-libp2p-peerstore/version.json | 3 - .../libp2p/go-libp2p-pubsub/backoff.go | 2 +- .../libp2p/go-libp2p-pubsub/blacklist.go | 2 +- .../libp2p/go-libp2p-pubsub/comm.go | 4 +- .../libp2p/go-libp2p-pubsub/discovery.go | 6 +- .../libp2p/go-libp2p-pubsub/floodsub.go | 6 +- .../libp2p/go-libp2p-pubsub/gossip_tracer.go | 4 +- .../libp2p/go-libp2p-pubsub/gossipsub.go | 12 +- .../libp2p/go-libp2p-pubsub/gossipsub_feat.go | 2 +- .../libp2p/go-libp2p-pubsub/mcache.go | 2 +- .../libp2p/go-libp2p-pubsub/notify.go | 4 +- .../libp2p/go-libp2p-pubsub/peer_gater.go | 8 +- .../libp2p/go-libp2p-pubsub/pubsub.go | 14 +- .../libp2p/go-libp2p-pubsub/randomsub.go | 6 +- .../libp2p/go-libp2p-pubsub/score.go | 15 +- .../libp2p/go-libp2p-pubsub/score_params.go | 221 +- .../libp2p/go-libp2p-pubsub/sign.go | 4 +- .../go-libp2p-pubsub/subscription_filter.go | 2 +- .../libp2p/go-libp2p-pubsub/tag_tracer.go | 20 +- .../libp2p/go-libp2p-pubsub/topic.go | 6 +- .../libp2p/go-libp2p-pubsub/trace.go | 4 +- .../libp2p/go-libp2p-pubsub/tracer.go | 10 +- .../libp2p/go-libp2p-pubsub/validation.go | 4 +- .../go-libp2p-resource-manager/.gitignore | 15 - .../libp2p/go-libp2p-resource-manager/LICENSE | 21 - .../go-libp2p-resource-manager/version.json | 3 - .../libp2p/go-libp2p/config/config.go | 37 +- .../go-libp2p/config/constructor_types.go | 48 +- .../libp2p/go-libp2p/config/muxer.go | 8 +- .../go-libp2p/config/reflection_magic.go | 20 +- .../libp2p/go-libp2p/config/security.go | 13 +- .../libp2p/go-libp2p/config/transport.go | 24 +- .../core}/canonicallog/canonicallog.go | 3 +- .../core}/connmgr/decay.go | 10 +- .../core}/connmgr/gater.go | 36 +- .../core}/connmgr/manager.go | 4 +- .../core}/connmgr/null.go | 4 +- .../core}/connmgr/presets.go | 0 .../core}/control/disconnect.go | 0 .../core}/crypto/ecdsa.go | 4 +- .../core}/crypto/ed25519.go | 4 +- .../core}/crypto/key.go | 2 +- .../core}/crypto/key_not_openssl.go | 10 +- .../core}/crypto/key_openssl.go | 14 +- .../core}/crypto/openssl_common.go | 2 +- .../core}/crypto/pb/Makefile | 0 .../core}/crypto/pb/crypto.pb.go | 0 .../core}/crypto/pb/crypto.proto | 2 +- .../core}/crypto/rsa_common.go | 0 .../core}/crypto/rsa_go.go | 4 +- .../core}/crypto/rsa_openssl.go | 0 .../core}/crypto/secp256k1.go | 38 +- .../core}/discovery/discovery.go | 2 +- .../core}/discovery/options.go | 0 .../core}/event/addrs.go | 3 +- .../core}/event/bus.go | 0 .../core}/event/dht.go | 0 .../libp2p/go-libp2p/core/event/doc.go | 11 + .../core}/event/identify.go | 2 +- .../core}/event/nattype.go | 2 +- .../core}/event/network.go | 28 +- .../core}/event/protocol.go | 4 +- .../core}/event/reachability.go | 2 +- .../core}/host/helpers.go | 2 +- .../core}/host/host.go | 14 +- .../core}/internal/catch/catch.go | 0 .../core}/introspection/doc.go | 0 .../core}/introspection/endpoint.go | 0 .../core}/introspection/introspector.go | 2 +- .../core}/introspection/pb/Makefile | 0 .../core}/introspection/pb/doc.go | 0 .../introspection/pb/introspection.pb.go | 11 +- .../introspection/pb/introspection.proto | 0 .../core}/metrics/bandwidth.go | 4 +- .../core}/metrics/reporter.go | 4 +- .../core}/network/conn.go | 7 +- .../core}/network/context.go | 0 .../core}/network/errors.go | 0 .../core}/network/mux.go | 0 .../core}/network/nattype.go | 0 .../core}/network/network.go | 4 +- .../core}/network/notifee.go | 0 .../core}/network/rcmgr.go | 59 +- .../core}/network/stream.go | 2 +- .../core}/peer/addrinfo.go | 0 .../core}/peer/addrinfo_serde.go | 3 +- .../core}/peer/pb/Makefile | 0 .../core}/peer/pb/peer_record.pb.go | 5 +- .../core}/peer/pb/peer_record.proto | 2 +- .../core}/peer/peer.go | 24 +- .../core}/peer/peer_serde.go | 0 .../core}/peer/record.go | 35 +- .../core}/peerstore/helpers.go | 2 +- .../core}/peerstore/peerstore.go | 13 +- .../core}/pnet/codec.go | 0 .../core}/pnet/env.go | 0 .../core}/pnet/error.go | 0 .../core}/pnet/protector.go | 0 .../core}/protocol/id.go | 0 .../core}/protocol/switch.go | 0 .../core}/record/envelope.go | 36 +- .../core}/record/pb/Makefile | 0 .../core}/record/pb/envelope.pb.go | 5 +- .../core}/record/pb/envelope.proto | 0 .../core}/record/record.go | 15 +- .../core}/routing/options.go | 0 .../core}/routing/query.go | 2 +- .../core}/routing/query_serde.go | 4 +- .../core}/routing/routing.go | 4 +- .../core}/sec/insecure/insecure.go | 10 +- .../core}/sec/insecure/pb/Makefile | 0 .../core}/sec/insecure/pb/plaintext.pb.go | 5 +- .../core}/sec/insecure/pb/plaintext.proto | 2 +- .../core}/sec/security.go | 4 +- .../core}/transport/transport.go | 10 +- .../github.com/libp2p/go-libp2p/defaults.go | 37 +- vendor/github.com/libp2p/go-libp2p/libp2p.go | 3 +- vendor/github.com/libp2p/go-libp2p/limits.go | 6 +- vendor/github.com/libp2p/go-libp2p/options.go | 42 +- .../libp2p/go-libp2p/options_filter.go | 8 +- .../p2p/discovery/backoff/backoffcache.go | 4 +- .../p2p/discovery/backoff/backoffconnector.go | 6 +- .../go-libp2p/p2p/host/autonat/autonat.go | 10 +- .../go-libp2p/p2p/host/autonat/client.go | 7 +- .../go-libp2p/p2p/host/autonat/dialpolicy.go | 3 +- .../go-libp2p/p2p/host/autonat/interface.go | 4 +- .../go-libp2p/p2p/host/autonat/notify.go | 2 +- .../go-libp2p/p2p/host/autonat/options.go | 4 +- .../go-libp2p/p2p/host/autonat/proto.go | 3 +- .../libp2p/go-libp2p/p2p/host/autonat/svc.go | 7 +- .../p2p/host/autorelay/addrsplosion.go | 4 +- .../go-libp2p/p2p/host/autorelay/autorelay.go | 43 +- .../go-libp2p/p2p/host/autorelay/host.go | 2 +- .../go-libp2p/p2p/host/autorelay/options.go | 90 +- .../p2p/host/autorelay/relay_finder.go | 323 +- .../go-libp2p/p2p/host/autorelay/timer.go | 42 + .../go-libp2p/p2p/host/basic/basic_host.go | 119 +- .../libp2p/go-libp2p/p2p/host/basic/natmgr.go | 9 +- .../p2p/host/basic/peer_connectedness.go | 6 +- .../libp2p/go-libp2p/p2p/host/blank/blank.go | 25 +- .../p2p/host/blank/peer_connectedness.go | 6 +- .../p2p/host/eventbus}/LICENSE-APACHE | 0 .../p2p/host/eventbus}/LICENSE-MIT | 0 .../p2p/host/eventbus}/basic.go | 8 +- .../p2p/host/eventbus}/opts.go | 2 +- .../p2p/host/peerstore}/metrics.go | 2 +- .../p2p/host/peerstore}/peerstore.go | 4 +- .../host/peerstore}/pstoremem/addr_book.go | 8 +- .../p2p/host/peerstore}/pstoremem/keybook.go | 7 +- .../p2p/host/peerstore}/pstoremem/metadata.go | 4 +- .../host/peerstore}/pstoremem/peerstore.go | 7 +- .../host/peerstore}/pstoremem/protobook.go | 5 +- .../p2p/host/peerstore}/pstoremem/sorting.go | 0 .../p2p/host/pstoremanager/pstoremanager.go | 8 +- .../go-libp2p/p2p/host/relaysvc/relay.go | 6 +- .../p2p/host/resource-manager}/README.md | 396 +- .../p2p/host/resource-manager}/allowlist.go | 3 +- .../p2p/host/resource-manager}/error.go | 2 +- .../p2p/host/resource-manager}/extapi.go | 6 +- .../p2p/host/resource-manager}/limit.go | 23 +- .../resource-manager}/limit_config_test.json | 0 .../host/resource-manager}/limit_defaults.go | 75 +- .../p2p/host/resource-manager}/metrics.go | 6 +- .../p2p/host/resource-manager}/rcmgr.go | 8 +- .../p2p/host/resource-manager}/scope.go | 55 +- .../host/resource-manager}/sys_not_unix.go | 0 .../p2p/host/resource-manager}/sys_unix.go | 0 .../p2p/host/resource-manager}/sys_windows.go | 0 .../p2p/host/resource-manager}/trace.go | 2 +- .../go-libp2p/p2p/host/routed/routed.go | 23 +- .../libp2p/go-libp2p/p2p/muxer/mplex/conn.go | 2 +- .../go-libp2p/p2p/muxer/mplex/stream.go | 2 +- .../go-libp2p/p2p/muxer/mplex/transport.go | 2 +- .../muxer/muxer-multistream/multistream.go | 2 +- .../libp2p/go-libp2p/p2p/muxer/yamux/conn.go | 4 +- .../go-libp2p/p2p/muxer/yamux/stream.go | 4 +- .../go-libp2p/p2p/muxer/yamux/transport.go | 17 +- .../p2p/net/conn-security-multistream/ssms.go | 5 +- .../go-libp2p/p2p/net/connmgr/connmgr.go | 70 +- .../libp2p/go-libp2p/p2p/net/connmgr/decay.go | 14 +- .../go-libp2p/p2p/net/connmgr/options.go | 11 + .../go-libp2p/p2p/net/connmgr/watchdog_cgo.go | 3 +- .../p2p/net/connmgr/watchdog_no_cgo.go | 3 +- .../go-libp2p/p2p/net/pnet/protector.go | 2 +- .../libp2p/go-libp2p/p2p/net/pnet/psk_conn.go | 2 +- .../go-libp2p/p2p/net/reuseport/dial.go | 57 +- .../go-libp2p/p2p/net/reuseport/dialer.go | 114 + .../p2p/net/reuseport/multidialer.go | 90 - .../p2p/net/reuseport/reuseport_posix.go | 1 - .../p2p/net/reuseport/singledialer.go | 16 - .../go-libp2p/p2p/net/reuseport/transport.go | 2 +- .../go-libp2p/p2p/net/swarm/dial_error.go | 2 +- .../go-libp2p/p2p/net/swarm/dial_sync.go | 4 +- .../go-libp2p/p2p/net/swarm/dial_worker.go | 4 +- .../libp2p/go-libp2p/p2p/net/swarm/limiter.go | 4 +- .../libp2p/go-libp2p/p2p/net/swarm/swarm.go | 24 +- .../go-libp2p/p2p/net/swarm/swarm_conn.go | 8 +- .../go-libp2p/p2p/net/swarm/swarm_dial.go | 153 +- .../go-libp2p/p2p/net/swarm/swarm_listen.go | 6 +- .../go-libp2p/p2p/net/swarm/swarm_stream.go | 4 +- .../p2p/net/swarm/swarm_transport.go | 20 +- .../libp2p/go-libp2p/p2p/net/upgrader/conn.go | 4 +- .../go-libp2p/p2p/net/upgrader/listener.go | 14 +- .../go-libp2p/p2p/net/upgrader/upgrader.go | 13 +- .../p2p/protocol/circuitv1/relay/options.go | 2 +- .../p2p/protocol/circuitv1/relay/relay.go | 7 +- .../p2p/protocol/circuitv2/client/client.go | 7 +- .../p2p/protocol/circuitv2/client/conn.go | 4 +- .../p2p/protocol/circuitv2/client/dial.go | 7 +- .../p2p/protocol/circuitv2/client/handlers.go | 3 +- .../protocol/circuitv2/client/reservation.go | 9 +- .../protocol/circuitv2/client/transport.go | 9 +- .../p2p/protocol/circuitv2/proto/voucher.go | 5 +- .../p2p/protocol/circuitv2/relay/acl.go | 2 +- .../protocol/circuitv2/relay/constraints.go | 3 +- .../p2p/protocol/circuitv2/relay/relay.go | 9 +- .../p2p/protocol/circuitv2/util/io.go | 8 +- .../p2p/protocol/circuitv2/util/pbconv.go | 3 +- .../p2p/protocol/holepunch/holepuncher.go | 7 +- .../go-libp2p/p2p/protocol/holepunch/svc.go | 13 +- .../p2p/protocol/holepunch/tracer.go | 2 +- .../go-libp2p/p2p/protocol/holepunch/util.go | 7 +- .../go-libp2p/p2p/protocol/identify/id.go | 65 +- .../p2p/protocol/identify/id_delta.go | 9 +- .../p2p/protocol/identify/id_go117.go | 1 - .../p2p/protocol/identify/id_go118.go | 1 - .../p2p/protocol/identify/id_push.go | 2 +- .../p2p/protocol/identify/obsaddr.go | 16 +- .../go-libp2p/p2p/protocol/identify/opts.go | 9 + .../p2p/protocol/identify/pb/identify.pb.go | 7 +- .../p2p/protocol/identify/pb/identify.proto | 4 +- .../p2p/protocol/identify/peer_loop.go | 9 +- .../go-libp2p/p2p/protocol/ping/ping.go | 6 +- .../go-libp2p/p2p/security/noise/handshake.go | 94 +- .../p2p/security/noise/pb/payload.pb.go | 261 +- .../p2p/security/noise/pb/payload.proto | 14 +- .../go-libp2p/p2p/security/noise/session.go | 26 +- .../p2p/security/noise/session_transport.go | 81 + .../go-libp2p/p2p/security/noise/transport.go | 25 +- .../libp2p/go-libp2p/p2p/security/tls/conn.go | 6 +- .../go-libp2p/p2p/security/tls/crypto.go | 116 +- .../go-libp2p/p2p/security/tls/transport.go | 9 +- .../go-libp2p/p2p/transport/quic/conn.go | 19 +- .../go-libp2p/p2p/transport/quic/listener.go | 29 +- .../go-libp2p/p2p/transport/quic/options.go | 33 + .../go-libp2p/p2p/transport/quic/stream.go | 2 +- .../go-libp2p/p2p/transport/quic/tracer.go | 14 +- .../p2p/transport/quic/tracer_metrics.go | 31 +- .../go-libp2p/p2p/transport/quic/transport.go | 114 +- .../go-libp2p/p2p/transport/tcp/metrics.go | 1 - .../p2p/transport/tcp/metrics_darwin.go | 1 - .../p2p/transport/tcp/metrics_general.go | 1 - .../p2p/transport/tcp/metrics_linux.go | 1 - .../p2p/transport/tcp/metrics_windows.go | 1 - .../go-libp2p/p2p/transport/tcp/reuseport.go | 2 +- .../libp2p/go-libp2p/p2p/transport/tcp/tcp.go | 34 +- .../p2p/transport/websocket/addrs.go | 62 +- .../p2p/transport/websocket/listener.go | 35 +- .../p2p/transport/websocket/websocket.go | 97 +- .../github.com/libp2p/go-libp2p/version.json | 2 +- vendor/github.com/libp2p/go-openssl/alloc.go | 19 + vendor/github.com/libp2p/go-openssl/bio.go | 78 +- vendor/github.com/libp2p/go-openssl/build.go | 1 + .../libp2p/go-openssl/build_static.go | 1 + vendor/github.com/libp2p/go-openssl/cert.go | 6 +- .../github.com/libp2p/go-openssl/ciphers.go | 10 +- .../libp2p/go-openssl/ciphers_gcm.go | 16 +- vendor/github.com/libp2p/go-openssl/conn.go | 35 +- vendor/github.com/libp2p/go-openssl/ctx.go | 59 +- vendor/github.com/libp2p/go-openssl/fips.go | 13 + vendor/github.com/libp2p/go-openssl/hmac.go | 2 +- .../github.com/libp2p/go-openssl/hostname.go | 34 +- vendor/github.com/libp2p/go-openssl/init.go | 5 +- .../libp2p/go-openssl/init_posix.go | 1 + .../libp2p/go-openssl/init_windows.go | 1 + vendor/github.com/libp2p/go-openssl/key.go | 38 +- vendor/github.com/libp2p/go-openssl/md4.go | 15 +- vendor/github.com/libp2p/go-openssl/md5.go | 10 +- vendor/github.com/libp2p/go-openssl/net.go | 21 +- vendor/github.com/libp2p/go-openssl/pem.go | 10 +- vendor/github.com/libp2p/go-openssl/sha1.go | 10 +- vendor/github.com/libp2p/go-openssl/sha256.go | 10 +- vendor/github.com/libp2p/go-openssl/shim.c | 10 +- vendor/github.com/libp2p/go-openssl/shim.h | 2 + vendor/github.com/libp2p/go-openssl/ssl.go | 8 +- .../github.com/libp2p/go-openssl/tickets.go | 4 +- .../libp2p/go-openssl/utils/future.go | 36 +- .../github.com/libp2p/go-openssl/version.json | 3 + .../libp2p/go-yamux/v3/version.json | 3 - .../libp2p/go-yamux/{v3 => v4}/.gitignore | 0 .../libp2p/go-yamux/{v3 => v4}/LICENSE | 0 .../libp2p/go-yamux/{v3 => v4}/LICENSE-BSD | 0 .../libp2p/go-yamux/{v3 => v4}/README.md | 0 .../libp2p/go-yamux/{v3 => v4}/addr.go | 0 .../libp2p/go-yamux/{v3 => v4}/const.go | 0 .../libp2p/go-yamux/{v3 => v4}/deadline.go | 0 .../libp2p/go-yamux/{v3 => v4}/mux.go | 12 +- .../libp2p/go-yamux/{v3 => v4}/ping.go | 0 .../libp2p/go-yamux/{v3 => v4}/session.go | 105 +- .../libp2p/go-yamux/{v3 => v4}/spec.md | 0 .../libp2p/go-yamux/{v3 => v4}/stream.go | 23 +- .../libp2p/go-yamux/{v3 => v4}/util.go | 26 +- .../libp2p/go-yamux/v4/version.json | 3 + .../lucas-clemente/quic-go/README.md | 8 +- .../lucas-clemente/quic-go/client.go | 11 +- .../lucas-clemente/quic-go/closed_conn.go | 86 +- .../lucas-clemente/quic-go/codecov.yml | 1 + .../lucas-clemente/quic-go/config.go | 44 +- .../quic-go/conn_id_generator.go | 23 +- .../lucas-clemente/quic-go/conn_id_manager.go | 17 +- .../lucas-clemente/quic-go/connection.go | 42 +- .../lucas-clemente/quic-go/crypto_stream.go | 4 +- .../lucas-clemente/quic-go/frame_sorter.go | 22 +- .../lucas-clemente/quic-go/interface.go | 53 +- .../quic-go/internal/ackhandler/ackhandler.go | 7 +- .../quic-go/internal/ackhandler/gen.go | 3 - .../quic-go/internal/ackhandler/interfaces.go | 4 + .../ackhandler/packet_number_generator.go | 2 +- .../ackhandler/received_packet_history.go | 18 +- .../ackhandler/received_packet_tracker.go | 2 +- .../ackhandler/sent_packet_handler.go | 23 +- .../ackhandler/sent_packet_history.go | 102 +- .../quic-go/internal/congestion/cubic.go | 2 +- .../internal/congestion/cubic_sender.go | 4 +- .../internal/congestion/hybrid_slow_start.go | 4 +- .../quic-go/internal/congestion/pacer.go | 6 +- .../flowcontrol/base_flow_controller.go | 2 +- .../flowcontrol/connection_flow_controller.go | 2 +- .../flowcontrol/stream_flow_controller.go | 2 +- .../quic-go/internal/handshake/aead.go | 2 +- .../internal/handshake/token_generator.go | 31 +- .../internal/handshake/updatable_aead.go | 2 +- .../internal/protocol/connection_id.go | 12 + .../quic-go/internal/qtls/go116.go | 100 - .../quic-go/internal/qtls/go117.go | 100 - .../quic-go/internal/qtls/go118.go | 1 - .../quic-go/internal/qtls/go119.go | 1 - .../quic-go/internal/qtls/go120.go | 1 - .../quic-go/internal/qtls/go_oldversion.go | 4 +- .../internal/utils/byteinterval_linkedlist.go | 217 - .../quic-go/internal/utils/gen.go | 5 - .../internal/utils/linkedlist/README.md | 4 + .../linkedlist/linkedlist.go} | 120 +- .../quic-go/internal/utils/minmax.go | 106 +- .../internal/utils/new_connection_id.go | 12 - .../utils/newconnectionid_linkedlist.go | 217 - .../quic-go/internal/utils/packet_interval.go | 9 - .../utils/packetinterval_linkedlist.go | 217 - .../quic-go/internal/utils/rtt_stats.go | 6 +- .../internal/utils/streamframe_interval.go | 9 - .../quic-go/internal/wire/header.go | 14 +- .../internal/wire/transport_parameters.go | 2 +- .../quic-go/logging/null_tracer.go | 52 + .../quic-go/packet_handler_map.go | 152 +- .../lucas-clemente/quic-go/packet_packer.go | 2 +- .../lucas-clemente/quic-go/send_stream.go | 4 +- .../lucas-clemente/quic-go/server.go | 98 +- .../lucas-clemente/quic-go/streams_map.go | 20 +- .../quic-go/streams_map_generic_helper.go | 18 - ...ncoming_uni.go => streams_map_incoming.go} | 57 +- .../quic-go/streams_map_incoming_bidi.go | 192 - .../quic-go/streams_map_incoming_generic.go | 190 - ...utgoing_uni.go => streams_map_outgoing.go} | 64 +- .../quic-go/streams_map_outgoing_bidi.go | 226 - .../quic-go/streams_map_outgoing_generic.go | 224 - .../lucas-clemente/quic-go/sys_conn_df.go | 1 - .../quic-go/sys_conn_df_linux.go | 1 - .../quic-go/sys_conn_df_windows.go | 1 - .../quic-go/sys_conn_helper_darwin.go | 1 - .../quic-go/sys_conn_helper_freebsd.go | 1 - .../quic-go/sys_conn_helper_linux.go | 1 - .../lucas-clemente/quic-go/sys_conn_no_oob.go | 1 - .../lucas-clemente/quic-go/sys_conn_oob.go | 1 - .../quic-go/sys_conn_windows.go | 1 - .../lucas-clemente/quic-go/tools.go | 3 +- .../lucas-clemente/quic-go/zero_rtt_queue.go | 34 + .../marten-seemann/qtls-go1-16/README.md | 6 - .../marten-seemann/qtls-go1-16/alert.go | 102 - .../marten-seemann/qtls-go1-16/auth.go | 289 - .../qtls-go1-16/cipher_suites.go | 532 - .../marten-seemann/qtls-go1-16/common.go | 1576 - .../marten-seemann/qtls-go1-16/common_js.go | 12 - .../marten-seemann/qtls-go1-16/common_nojs.go | 20 - .../marten-seemann/qtls-go1-16/conn.go | 1536 - .../qtls-go1-16/handshake_client.go | 1105 - .../qtls-go1-16/handshake_client_tls13.go | 740 - .../qtls-go1-16/handshake_messages.go | 1832 - .../qtls-go1-16/handshake_server.go | 878 - .../qtls-go1-16/handshake_server_tls13.go | 912 - .../qtls-go1-16/key_agreement.go | 338 - .../qtls-go1-16/key_schedule.go | 199 - .../marten-seemann/qtls-go1-16/prf.go | 283 - .../marten-seemann/qtls-go1-16/ticket.go | 259 - .../marten-seemann/qtls-go1-16/tls.go | 393 - .../marten-seemann/qtls-go1-16/unsafe.go | 96 - .../marten-seemann/qtls-go1-17/README.md | 6 - .../marten-seemann/qtls-go1-17/alert.go | 102 - .../marten-seemann/qtls-go1-17/auth.go | 289 - .../qtls-go1-17/cipher_suites.go | 691 - .../marten-seemann/qtls-go1-17/common.go | 1485 - .../marten-seemann/qtls-go1-17/conn.go | 1601 - .../marten-seemann/qtls-go1-17/cpu.go | 22 - .../marten-seemann/qtls-go1-17/cpu_other.go | 12 - .../qtls-go1-17/handshake_client.go | 1111 - .../qtls-go1-17/handshake_client_tls13.go | 732 - .../qtls-go1-17/handshake_messages.go | 1832 - .../qtls-go1-17/handshake_server.go | 905 - .../qtls-go1-17/handshake_server_tls13.go | 896 - .../qtls-go1-17/key_agreement.go | 357 - .../qtls-go1-17/key_schedule.go | 199 - .../marten-seemann/qtls-go1-17/prf.go | 283 - .../marten-seemann/qtls-go1-17/ticket.go | 274 - .../marten-seemann/qtls-go1-17/tls.go | 362 - .../marten-seemann/qtls-go1-17/unsafe.go | 96 - .../genny => mattn/go-pointer}/LICENSE | 3 +- vendor/github.com/mattn/go-pointer/README.md | 29 + .../mattn/go-pointer/_example/callback.h | 9 + vendor/github.com/mattn/go-pointer/doc.go | 1 + vendor/github.com/mattn/go-pointer/pointer.go | 57 + .../multiformats/go-base32/base32.go | 3 +- .../multiformats/go-base32/version.json | 3 + .../multiformats/go-multiaddr/doc.go | 41 +- .../multiformats/go-multiaddr/filter.go | 5 +- .../multiformats/go-multiaddr/interface.go | 13 +- .../multiformats/go-multiaddr/net/net.go | 16 +- .../multiformats/go-multiaddr/protocols.go | 82 +- .../multiformats/go-multiaddr/version.json | 2 +- .../multiformats/go-multicodec/version.json | 2 +- .../multiformats/go-multihash/core/magic.go | 3 + .../go-multihash/core/registry.go | 52 +- .../multiformats/go-multihash/multihash.go | 15 +- .../register/blake3/multihash_blake3.go | 14 +- .../multiformats/go-multihash/sum.go | 7 +- .../multiformats/go-multihash/version.json | 2 +- .../client_golang/prometheus/collector.go | 6 +- .../client_golang/prometheus/counter.go | 2 +- .../client_golang/prometheus/desc.go | 5 +- .../client_golang/prometheus/get_pid.go | 26 + .../prometheus/get_pid_gopherjs.go | 23 + .../client_golang/prometheus/go_collector.go | 20 +- .../prometheus/go_collector_go116.go | 17 +- ...lector_go117.go => go_collector_latest.go} | 314 +- .../client_golang/prometheus/histogram.go | 2 +- .../prometheus/internal/difflib.go | 651 + .../internal/go_collector_options.go | 32 + .../prometheus/internal/go_runtime_metrics.go | 18 +- .../prometheus/internal/metric.go | 28 +- .../client_golang/prometheus/labels.go | 6 +- .../client_golang/prometheus/metric.go | 112 +- .../client_golang/prometheus/num_threads.go | 25 + .../prometheus/num_threads_gopherjs.go | 22 + .../client_golang/prometheus/observer.go | 2 +- .../prometheus/process_collector.go | 10 +- .../prometheus/process_collector_js.go | 26 + .../prometheus/process_collector_other.go | 4 +- .../prometheus/promhttp/delegator.go | 18 +- .../client_golang/prometheus/promhttp/http.go | 20 +- .../prometheus/promhttp/instrument_client.go | 39 +- .../prometheus/promhttp/instrument_server.go | 119 +- .../prometheus/promhttp/option.go | 39 +- .../client_golang/prometheus/registry.go | 118 +- .../client_golang/prometheus/value.go | 47 +- .../client_golang/prometheus/vec.go | 88 +- .../client_golang/prometheus/wrap.go | 4 +- .../github.com/prometheus/procfs/.gitignore | 3 +- .../prometheus/procfs/.golangci.yml | 10 +- .../prometheus/procfs/CODE_OF_CONDUCT.md | 4 +- .../prometheus/procfs/CONTRIBUTING.md | 4 +- vendor/github.com/prometheus/procfs/Makefile | 10 +- .../prometheus/procfs/Makefile.common | 89 +- .../github.com/prometheus/procfs/SECURITY.md | 2 +- vendor/github.com/prometheus/procfs/arp.go | 45 +- .../github.com/prometheus/procfs/cpuinfo.go | 5 +- .../prometheus/procfs/cpuinfo_armx.go | 1 + .../prometheus/procfs/cpuinfo_mipsx.go | 1 + .../prometheus/procfs/cpuinfo_others.go | 4 +- .../prometheus/procfs/cpuinfo_ppcx.go | 1 + .../prometheus/procfs/cpuinfo_riscvx.go | 1 + .../prometheus/procfs/cpuinfo_s390x.go | 1 + .../prometheus/procfs/cpuinfo_x86.go | 1 + .../prometheus/procfs/fixtures.ttar | 7673 ----- .../prometheus/procfs/internal/fs/fs.go | 2 +- .../prometheus/procfs/internal/util/parse.go | 6 +- .../procfs/internal/util/readfile.go | 11 +- .../procfs/internal/util/sysreadfile.go | 8 +- .../internal/util/sysreadfile_compat.go | 3 +- vendor/github.com/prometheus/procfs/ipvs.go | 3 +- .../prometheus/procfs/kernel_random.go | 1 + .../github.com/prometheus/procfs/loadavg.go | 2 +- vendor/github.com/prometheus/procfs/mdstat.go | 10 +- .../prometheus/procfs/net_conntrackstat.go | 12 +- .../github.com/prometheus/procfs/net_dev.go | 8 +- .../prometheus/procfs/net_ip_socket.go | 2 +- .../prometheus/procfs/net_protocols.go | 4 +- .../prometheus/procfs/net_softnet.go | 8 +- .../procfs/{xfrm.go => net_xfrm.go} | 9 +- .../github.com/prometheus/procfs/netstat.go | 8 +- vendor/github.com/prometheus/procfs/proc.go | 10 +- .../prometheus/procfs/proc_cgroup.go | 6 +- .../prometheus/procfs/proc_cgroups.go | 98 + .../prometheus/procfs/proc_environ.go | 2 +- .../prometheus/procfs/proc_fdinfo.go | 3 +- .../prometheus/procfs/proc_limits.go | 2 +- .../github.com/prometheus/procfs/proc_maps.go | 12 +- .../prometheus/procfs/proc_netstat.go | 440 + .../github.com/prometheus/procfs/proc_psi.go | 14 +- .../prometheus/procfs/proc_smaps.go | 23 +- .../github.com/prometheus/procfs/proc_snmp.go | 353 + .../prometheus/procfs/proc_snmp6.go | 381 + .../github.com/prometheus/procfs/proc_stat.go | 11 +- .../prometheus/procfs/proc_status.go | 32 +- .../github.com/prometheus/procfs/proc_sys.go | 51 + .../github.com/prometheus/procfs/schedstat.go | 6 +- vendor/github.com/prometheus/procfs/slab.go | 2 +- .../github.com/prometheus/procfs/softirqs.go | 160 + vendor/github.com/prometheus/procfs/stat.go | 10 +- vendor/github.com/prometheus/procfs/vm.go | 6 +- .../github.com/prometheus/procfs/zoneinfo.go | 5 +- .../status-im/go-multiaddr-ethv4/protocol.go | 4 +- .../status-im/go-waku-rendezvous/.gitignore | 14 - .../status-im/go-waku-rendezvous/LICENSE | 21 - .../status-im/go-waku-rendezvous/README.md | 157 - .../status-im/go-waku-rendezvous/cleaner.go | 104 - .../status-im/go-waku-rendezvous/client.go | 352 - .../status-im/go-waku-rendezvous/discovery.go | 151 - .../go-waku-rendezvous/pb/rendezvous.pb.go | 1659 - .../go-waku-rendezvous/pb/rendezvous.proto | 51 - .../status-im/go-waku-rendezvous/proto.go | 139 - .../status-im/go-waku-rendezvous/storage.go | 161 - .../status-im/go-waku-rendezvous/svc.go | 247 - .../status-im/go-waku/logging/logging.go | 29 +- .../waku/persistence/migrations/migrate.go | 4 +- .../persistence/migrations/no_migrations.go | 4 +- .../go-waku/waku/persistence/rendezvous.go | 40 - .../go-waku/waku/v2/discv5/discover.go | 12 +- .../go-waku/waku/v2/node/connectedness.go | 12 +- .../go-waku/waku/v2/node/keepalive.go | 4 +- .../go-waku/waku/v2/node/wakunode2.go | 63 +- .../go-waku/waku/v2/node/wakunode2_rln.go | 2 +- .../go-waku/waku/v2/node/wakuoptions.go | 35 +- .../go-waku/waku/v2/node/wakuoptions_rln.go | 20 +- .../go-waku/waku/v2/noise/handshake.go | 6 +- .../go-waku/waku/v2/noise/patterns.go | 46 +- .../go-waku/waku/v2/noise/payload.go | 2 +- .../go-waku/waku/v2/protocol/envelope.go | 7 +- .../v2/protocol/filter/filter_subscribers.go | 2 +- .../waku/v2/protocol/filter/waku_filter.go | 8 +- .../v2/protocol/filter/waku_filter_option.go | 4 +- .../v2/protocol/lightpush/waku_lightpush.go | 23 +- .../lightpush/waku_lightpush_option.go | 4 +- .../go-waku/waku/v2/protocol/pb/utils.go | 6 +- .../waku/v2/protocol/relay/waku_relay.go | 10 +- .../waku/v2/protocol/rln/rln_relay_builder.go | 44 +- .../waku/v2/protocol/rln/waku_rln_relay.go | 71 +- .../go-waku/waku/v2/protocol/rln/web3.go | 35 +- .../waku/v2/protocol/store/waku_store.go | 15 +- .../waku/v2/protocol/swap/waku_swap.go | 2 +- .../status-im/go-waku/waku/v2/utils/crypto.go | 6 +- .../status-im/go-waku/waku/v2/utils/enr.go | 36 +- .../status-im/go-waku/waku/v2/utils/logger.go | 66 +- .../status-im/go-waku/waku/v2/utils/peer.go | 4 +- .../github.com/status-im/rendezvous/client.go | 8 +- .../status-im/rendezvous/server/server.go | 6 +- .../github.com/status-im/rendezvous/stream.go | 4 +- vendor/github.com/urfave/cli/v2/app.go | 292 +- vendor/github.com/urfave/cli/v2/category.go | 4 +- vendor/github.com/urfave/cli/v2/cli.go | 2 +- vendor/github.com/urfave/cli/v2/command.go | 273 +- vendor/github.com/urfave/cli/v2/flag_bool.go | 5 +- .../github.com/urfave/cli/v2/flag_duration.go | 5 +- .../github.com/urfave/cli/v2/flag_generic.go | 23 +- vendor/github.com/urfave/cli/v2/flag_int.go | 5 +- vendor/github.com/urfave/cli/v2/flag_int64.go | 5 +- vendor/github.com/urfave/cli/v2/flag_path.go | 9 +- .../github.com/urfave/cli/v2/flag_string.go | 9 +- .../urfave/cli/v2/flag_timestamp.go | 27 +- vendor/github.com/urfave/cli/v2/flag_uint.go | 5 +- .../github.com/urfave/cli/v2/flag_uint64.go | 5 +- .../urfave/cli/v2/godoc-current.txt | 90 +- vendor/github.com/urfave/cli/v2/help.go | 42 +- vendor/github.com/urfave/cli/v2/parse.go | 12 +- vendor/github.com/urfave/cli/v2/template.go | 82 +- .../urfave/cli/v2/zz_generated.flags.go | 34 + .../go-discover/COPYING.LESSER | 0 .../go-discover/discover/common.go | 22 +- .../go-discover/discover/lookup.go | 3 +- .../go-discover/discover/node.go | 0 .../go-discover/discover/ntp.go | 2 +- .../go-discover/discover/table.go | 2 - .../go-discover/discover/v4_udp.go | 10 +- .../go-discover/discover/v4wire/v4wire.go | 15 +- .../go-discover/discover/v5_udp.go | 19 +- .../go-discover/discover/v5wire/crypto.go | 0 .../go-discover/discover/v5wire/encoding.go | 30 +- .../go-discover/discover/v5wire/msg.go | 26 +- .../go-discover/discover/v5wire/session.go | 0 .../go-zerokit-rln/LICENSE | 0 .../go-zerokit-rln/rln/librln.h | 5 + .../go-zerokit-rln/rln/link.go | 0 .../go-zerokit-rln/rln/resources/bindata.go | 0 .../go-zerokit-rln/rln/resources/doc.go | 0 .../go-zerokit-rln/rln/rln.go | 31 +- .../go-zerokit-rln/rln/serialize.go | 0 .../go-zerokit-rln/rln/types.go | 27 +- .../go-zerokit-rln/rln/utils.go | 0 .../github.com/waku-org/noise/CONTRIBUTING.md | 1 + .../qtls-go1-17 => waku-org/noise}/LICENSE | 6 +- vendor/github.com/waku-org/noise/README.md | 5 + .../github.com/waku-org/noise/cipher_suite.go | 224 + vendor/github.com/waku-org/noise/hkdf.go | 49 + vendor/github.com/waku-org/noise/patterns.go | 141 + vendor/github.com/waku-org/noise/state.go | 620 + vendor/github.com/waku-org/noise/vectors.txt | 28640 ++++++++++++++++ vendor/go.uber.org/atomic/CHANGELOG.md | 17 + vendor/go.uber.org/atomic/bool.go | 11 +- vendor/go.uber.org/atomic/duration.go | 11 +- vendor/go.uber.org/atomic/error.go | 13 +- vendor/go.uber.org/atomic/error_ext.go | 4 +- vendor/go.uber.org/atomic/float32.go | 77 + vendor/go.uber.org/atomic/float32_ext.go | 76 + vendor/go.uber.org/atomic/float64.go | 2 +- vendor/go.uber.org/atomic/float64_ext.go | 37 +- vendor/go.uber.org/atomic/int32.go | 9 +- vendor/go.uber.org/atomic/int64.go | 9 +- vendor/go.uber.org/atomic/nocmp.go | 12 +- vendor/go.uber.org/atomic/pointer_go118.go | 60 + vendor/go.uber.org/atomic/pointer_go119.go | 61 + vendor/go.uber.org/atomic/string.go | 13 +- vendor/go.uber.org/atomic/string_ext.go | 6 +- vendor/go.uber.org/atomic/time.go | 2 +- vendor/go.uber.org/atomic/uint32.go | 9 +- vendor/go.uber.org/atomic/uint64.go | 9 +- vendor/go.uber.org/atomic/uintptr.go | 9 +- vendor/go.uber.org/atomic/unsafe_pointer.go | 9 +- vendor/go.uber.org/atomic/value.go | 4 +- vendor/go.uber.org/zap/CHANGELOG.md | 12 + vendor/go.uber.org/zap/array_go118.go | 34 +- .../go.uber.org/zap/internal/level_enabler.go | 35 + vendor/go.uber.org/zap/level.go | 3 + vendor/go.uber.org/zap/writer.go | 4 +- vendor/go.uber.org/zap/zapcore/core.go | 9 + vendor/go.uber.org/zap/zapcore/hook.go | 9 + .../go.uber.org/zap/zapcore/increase_level.go | 9 + vendor/go.uber.org/zap/zapcore/level.go | 42 + vendor/go.uber.org/zap/zapcore/sampler.go | 11 +- vendor/go.uber.org/zap/zapcore/tee.go | 17 +- .../qtls-go1-16 => golang.org/x/exp}/LICENSE | 0 vendor/golang.org/x/exp/PATENTS | 22 + .../x/exp/constraints/constraints.go | 50 + vendor/golang.org/x/mod/modfile/print.go | 174 + vendor/golang.org/x/mod/modfile/read.go | 958 + vendor/golang.org/x/mod/modfile/rule.go | 1556 + vendor/golang.org/x/mod/modfile/work.go | 234 + vendor/golang.org/x/net/AUTHORS | 3 - vendor/golang.org/x/net/CONTRIBUTORS | 3 - .../golang.org/x/net/bpf/vm_instructions.go | 4 +- vendor/golang.org/x/net/context/go17.go | 4 +- .../x/net/dns/dnsmessage/message.go | 16 +- vendor/golang.org/x/net/html/render.go | 4 +- vendor/golang.org/x/net/html/token.go | 4 +- .../x/net/internal/socket/rawconn_msg.go | 48 +- .../x/net/internal/socket/sys_stub.go | 6 +- .../x/net/internal/socket/sys_unix.go | 101 +- .../x/net/internal/socket/sys_windows.go | 7 +- .../x/net/internal/socket/sys_zos_s390x.go | 38 +- .../x/net/internal/socket/zsys_darwin_386.go | 30 - ..._darwin_arm.go => zsys_freebsd_riscv64.go} | 8 +- .../x/net/ipv4/zsys_freebsd_riscv64.go | 52 + .../x/net/ipv6/zsys_freebsd_riscv64.go | 64 + vendor/golang.org/x/net/route/address.go | 37 +- .../x/net/route/interface_classic.go | 11 +- .../x/net/route/interface_freebsd.go | 12 +- .../x/net/route/interface_openbsd.go | 8 +- vendor/golang.org/x/net/route/route.go | 2 +- .../golang.org/x/net/route/route_openbsd.go | 6 +- vendor/golang.org/x/net/route/sys.go | 7 +- vendor/golang.org/x/net/route/sys_darwin.go | 38 +- .../golang.org/x/net/route/sys_dragonfly.go | 30 +- vendor/golang.org/x/net/route/sys_freebsd.go | 30 +- vendor/golang.org/x/net/route/sys_netbsd.go | 28 +- vendor/golang.org/x/net/route/sys_openbsd.go | 34 +- vendor/golang.org/x/net/route/zsys_darwin.go | 77 - .../golang.org/x/net/route/zsys_dragonfly.go | 78 - .../x/net/route/zsys_freebsd_386.go | 71 - .../x/net/route/zsys_freebsd_amd64.go | 71 - .../x/net/route/zsys_freebsd_arm.go | 71 - .../x/net/route/zsys_freebsd_arm64.go | 71 - .../x/net/route/zsys_freebsd_riscv64.go | 52 + vendor/golang.org/x/net/route/zsys_netbsd.go | 80 - vendor/golang.org/x/net/route/zsys_openbsd.go | 89 - vendor/golang.org/x/sync/AUTHORS | 3 - vendor/golang.org/x/sync/CONTRIBUTORS | 3 - vendor/golang.org/x/sync/errgroup/errgroup.go | 7 +- .../x/sync/singleflight/singleflight.go | 11 +- vendor/golang.org/x/text/AUTHORS | 3 - vendor/golang.org/x/text/CONTRIBUTORS | 3 - .../x/text/encoding/htmlindex/tables.go | 9 + .../text/encoding/internal/identifier/mib.go | 8 + .../x/text/encoding/simplifiedchinese/gbk.go | 6 +- .../text/internal/language/compact/tables.go | 6 +- .../x/text/internal/language/lookup.go | 4 +- .../x/text/internal/language/parse.go | 24 +- .../x/text/internal/language/tables.go | 868 +- .../internal/utf8internal/utf8internal.go | 2 +- vendor/golang.org/x/text/language/doc.go | 44 +- vendor/golang.org/x/text/language/go1_1.go | 39 - vendor/golang.org/x/text/language/go1_2.go | 12 - vendor/golang.org/x/text/language/match.go | 2 +- vendor/golang.org/x/text/language/parse.go | 8 +- vendor/golang.org/x/text/language/tables.go | 18 +- vendor/golang.org/x/text/runes/runes.go | 2 +- vendor/golang.org/x/text/unicode/bidi/core.go | 26 +- .../x/text/unicode/norm/forminfo.go | 9 +- .../x/text/unicode/norm/normalize.go | 11 +- .../x/text/unicode/norm/tables13.0.0.go | 4 +- vendor/golang.org/x/tools/AUTHORS | 3 - vendor/golang.org/x/tools/CONTRIBUTORS | 3 - .../x/tools/go/gcexportdata/gcexportdata.go | 48 +- .../x/tools/go/gcexportdata/importer.go | 3 + .../go/internal/gcimporter/gcimporter.go | 28 +- .../x/tools/go/internal/gcimporter/iimport.go | 60 +- .../go/internal/gcimporter/unified_no.go | 10 + .../go/internal/gcimporter/unified_yes.go | 10 + .../go/internal/gcimporter/ureader_no.go | 19 + .../go/internal/gcimporter/ureader_yes.go | 612 + .../x/tools/go/internal/pkgbits/codes.go | 77 + .../x/tools/go/internal/pkgbits/decoder.go | 433 + .../x/tools/go/internal/pkgbits/doc.go | 32 + .../x/tools/go/internal/pkgbits/encoder.go | 379 + .../x/tools/go/internal/pkgbits/flags.go | 9 + .../x/tools/go/internal/pkgbits/frames_go1.go | 21 + .../tools/go/internal/pkgbits/frames_go17.go | 28 + .../x/tools/go/internal/pkgbits/reloc.go | 42 + .../x/tools/go/internal/pkgbits/support.go | 17 + .../x/tools/go/internal/pkgbits/sync.go | 113 + .../go/internal/pkgbits/syncmarker_string.go | 89 + .../golang.org/x/tools/go/packages/golist.go | 7 +- .../x/tools/internal/imports/fix.go | 4 +- .../x/tools/internal/imports/mod.go | 14 +- vendor/google.golang.org/protobuf/AUTHORS | 3 - .../google.golang.org/protobuf/CONTRIBUTORS | 3 - .../protobuf/encoding/prototext/decode.go | 116 +- .../protobuf/encoding/prototext/encode.go | 39 +- .../protobuf/encoding/protowire/wire.go | 4 + .../protobuf/internal/descfmt/stringer.go | 66 +- .../internal/encoding/defval/default.go | 78 +- .../encoding/messageset/messageset.go | 7 +- .../protobuf/internal/encoding/tag/tag.go | 96 +- .../protobuf/internal/encoding/text/decode.go | 30 +- .../internal/encoding/text/decode_number.go | 6 +- .../protobuf/internal/encoding/text/doc.go | 4 +- .../protobuf/internal/filedesc/build.go | 19 +- .../protobuf/internal/filedesc/desc.go | 378 +- .../protobuf/internal/filedesc/desc_init.go | 36 +- .../protobuf/internal/filedesc/desc_lazy.go | 80 +- .../protobuf/internal/filedesc/desc_list.go | 167 +- .../protobuf/internal/filedesc/placeholder.go | 136 +- .../protobuf/internal/filetype/build.go | 87 +- .../protobuf/internal/impl/api_export.go | 42 +- .../protobuf/internal/impl/checkinit.go | 12 +- .../protobuf/internal/impl/codec_extension.go | 36 +- .../protobuf/internal/impl/codec_field.go | 90 +- .../protobuf/internal/impl/codec_map.go | 20 +- .../protobuf/internal/impl/codec_message.go | 30 +- .../protobuf/internal/impl/codec_tables.go | 290 +- .../protobuf/internal/impl/convert.go | 228 +- .../protobuf/internal/impl/convert_list.go | 42 +- .../protobuf/internal/impl/convert_map.go | 32 +- .../protobuf/internal/impl/decode.go | 21 +- .../protobuf/internal/impl/enum.go | 10 +- .../protobuf/internal/impl/extension.go | 26 +- .../protobuf/internal/impl/legacy_enum.go | 57 +- .../protobuf/internal/impl/legacy_export.go | 18 +- .../internal/impl/legacy_extension.go | 100 +- .../protobuf/internal/impl/legacy_message.go | 122 +- .../protobuf/internal/impl/merge.go | 32 +- .../protobuf/internal/impl/message.go | 41 +- .../protobuf/internal/impl/message_reflect.go | 74 +- .../internal/impl/message_reflect_field.go | 118 +- .../protobuf/internal/impl/validate.go | 50 +- .../protobuf/internal/impl/weak.go | 16 +- .../protobuf/internal/order/order.go | 16 +- .../protobuf/internal/order/range.go | 22 +- .../protobuf/internal/strs/strings_unsafe.go | 6 +- .../protobuf/internal/version/version.go | 54 +- .../protobuf/proto/decode.go | 3 +- .../google.golang.org/protobuf/proto/doc.go | 21 +- .../protobuf/proto/encode.go | 5 +- .../google.golang.org/protobuf/proto/equal.go | 50 +- .../reflect/protodesc/desc_resolve.go | 6 +- .../protobuf/reflect/protoreflect/proto.go | 30 +- .../protobuf/reflect/protoreflect/source.go | 1 + .../protobuf/reflect/protoreflect/type.go | 1 + .../reflect/protoreflect/value_union.go | 2 + .../reflect/protoregistry/registry.go | 2 + .../protobuf/runtime/protoimpl/version.go | 8 +- 947 files changed, 56392 insertions(+), 52734 deletions(-) delete mode 100644 vendor/github.com/cheekybits/genny/.gitignore delete mode 100644 vendor/github.com/cheekybits/genny/.travis.yml delete mode 100644 vendor/github.com/cheekybits/genny/README.md delete mode 100644 vendor/github.com/cheekybits/genny/doc.go delete mode 100644 vendor/github.com/cheekybits/genny/generic/doc.go delete mode 100644 vendor/github.com/cheekybits/genny/generic/generic.go delete mode 100644 vendor/github.com/cheekybits/genny/main.go delete mode 100644 vendor/github.com/cheekybits/genny/out/lazy_file.go delete mode 100644 vendor/github.com/cheekybits/genny/parse/builtins.go delete mode 100644 vendor/github.com/cheekybits/genny/parse/doc.go delete mode 100644 vendor/github.com/cheekybits/genny/parse/errors.go delete mode 100644 vendor/github.com/cheekybits/genny/parse/parse.go delete mode 100644 vendor/github.com/cheekybits/genny/parse/typesets.go delete mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go delete mode 100644 vendor/github.com/gogo/protobuf/io/full.go delete mode 100644 vendor/github.com/gogo/protobuf/io/io.go delete mode 100644 vendor/github.com/gogo/protobuf/io/uint32.go delete mode 100644 vendor/github.com/gogo/protobuf/io/varint.go create mode 100644 vendor/github.com/golang/mock/mockgen/mockgen.go create mode 100644 vendor/github.com/golang/mock/mockgen/model/model.go create mode 100644 vendor/github.com/golang/mock/mockgen/parse.go create mode 100644 vendor/github.com/golang/mock/mockgen/reflect.go create mode 100644 vendor/github.com/golang/mock/mockgen/version.1.11.go create mode 100644 vendor/github.com/golang/mock/mockgen/version.1.12.go delete mode 100644 vendor/github.com/ipfs/go-datastore/.gitignore delete mode 100644 vendor/github.com/ipfs/go-datastore/LICENSE delete mode 100644 vendor/github.com/ipfs/go-datastore/README.md delete mode 100644 vendor/github.com/ipfs/go-datastore/basic_ds.go delete mode 100644 vendor/github.com/ipfs/go-datastore/batch.go delete mode 100644 vendor/github.com/ipfs/go-datastore/datastore.go delete mode 100644 vendor/github.com/ipfs/go-datastore/key.go delete mode 100644 vendor/github.com/ipfs/go-datastore/query/filter.go delete mode 100644 vendor/github.com/ipfs/go-datastore/query/order.go delete mode 100644 vendor/github.com/ipfs/go-datastore/query/query.go delete mode 100644 vendor/github.com/ipfs/go-datastore/query/query_impl.go delete mode 100644 vendor/github.com/ipfs/go-datastore/version.json delete mode 100644 vendor/github.com/ipfs/go-ds-sql/LICENSE delete mode 100644 vendor/github.com/ipfs/go-ds-sql/README.md delete mode 100644 vendor/github.com/ipfs/go-ds-sql/batching.go delete mode 100644 vendor/github.com/ipfs/go-ds-sql/dstore.go delete mode 100644 vendor/github.com/ipfs/go-ds-sql/package.json delete mode 100644 vendor/github.com/ipfs/go-ds-sql/txn.go delete mode 100644 vendor/github.com/ipfs/go-ds-sql/version.json delete mode 100644 vendor/github.com/jbenet/goprocess/.travis.yml delete mode 100644 vendor/github.com/jbenet/goprocess/LICENSE delete mode 100644 vendor/github.com/jbenet/goprocess/README.md delete mode 100644 vendor/github.com/jbenet/goprocess/background.go delete mode 100644 vendor/github.com/jbenet/goprocess/goprocess.go delete mode 100644 vendor/github.com/jbenet/goprocess/impl-mutex.go delete mode 100644 vendor/github.com/jbenet/goprocess/link.go delete mode 100644 vendor/github.com/jbenet/goprocess/package.json delete mode 100644 vendor/github.com/klauspost/compress/huff0/autogen.go delete mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s delete mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in delete mode 100644 vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in create mode 100644 vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go create mode 100644 vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go create mode 100644 vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go delete mode 100644 vendor/github.com/klauspost/compress/zstd/fuzz.go delete mode 100644 vendor/github.com/klauspost/compress/zstd/fuzz_none.go create mode 100644 vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go create mode 100644 vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s create mode 100644 vendor/github.com/klauspost/compress/zstd/seqdec_generic.go delete mode 100644 vendor/github.com/libp2p/go-eventbus/.travis.yml delete mode 100644 vendor/github.com/libp2p/go-eventbus/README.md delete mode 100644 vendor/github.com/libp2p/go-eventbus/codecov.yml delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/LICENSE delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/LICENSE-APACHE delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/LICENSE-MIT delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/event/doc.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/test/addrs.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/test/crypto.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/test/errors.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-core/test/peer.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/.gitignore delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/LICENSE delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/README.md delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/codecov.yml delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pb/Makefile delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pb/custom.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.pb.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.proto delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book_gc.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cache.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cyclic_batch.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/keybook.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/metadata.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/peerstore.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/protobook.go delete mode 100644 vendor/github.com/libp2p/go-libp2p-peerstore/version.json delete mode 100644 vendor/github.com/libp2p/go-libp2p-resource-manager/.gitignore delete mode 100644 vendor/github.com/libp2p/go-libp2p-resource-manager/LICENSE delete mode 100644 vendor/github.com/libp2p/go-libp2p-resource-manager/version.json rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/canonicallog/canonicallog.go (98%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/connmgr/decay.go (92%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/connmgr/gater.go (72%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/connmgr/manager.go (97%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/connmgr/null.go (91%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/connmgr/presets.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/control/disconnect.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/ecdsa.go (98%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/ed25519.go (97%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/key.go (99%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/key_not_openssl.go (86%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/key_openssl.go (87%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/openssl_common.go (97%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/pb/Makefile (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/pb/crypto.pb.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/pb/crypto.proto (80%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/rsa_common.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/rsa_go.go (97%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/rsa_openssl.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/crypto/secp256k1.go (74%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/discovery/discovery.go (94%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/discovery/options.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/addrs.go (98%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/bus.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/dht.go (100%) create mode 100644 vendor/github.com/libp2p/go-libp2p/core/event/doc.go rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/identify.go (91%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/nattype.go (95%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/network.go (60%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/protocol.go (89%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/event/reachability.go (86%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/host/helpers.go (81%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/host/host.go (90%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/internal/catch/catch.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/introspection/doc.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/introspection/endpoint.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/introspection/introspector.go (95%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/introspection/pb/Makefile (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/introspection/pb/doc.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/introspection/pb/introspection.pb.go (99%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/introspection/pb/introspection.proto (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/metrics/bandwidth.go (98%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/metrics/reporter.go (90%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/conn.go (94%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/context.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/errors.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/mux.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/nattype.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/network.go (98%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/notifee.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/rcmgr.go (88%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/network/stream.go (94%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/addrinfo.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/addrinfo_serde.go (95%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/pb/Makefile (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/pb/peer_record.pb.go (99%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/pb/peer_record.proto (94%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/peer.go (93%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/peer_serde.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peer/record.go (90%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peerstore/helpers.go (87%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/peerstore/peerstore.go (97%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/pnet/codec.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/pnet/env.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/pnet/error.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/pnet/protector.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/protocol/id.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/protocol/switch.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/record/envelope.go (93%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/record/pb/Makefile (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/record/pb/envelope.pb.go (99%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/record/pb/envelope.proto (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/record/record.go (93%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/routing/options.go (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/routing/query.go (98%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/routing/query_serde.go (89%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/routing/routing.go (98%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/sec/insecure/insecure.go (97%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/sec/insecure/pb/Makefile (100%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/sec/insecure/pb/plaintext.pb.go (99%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/sec/insecure/pb/plaintext.proto (68%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/sec/security.go (94%) rename vendor/github.com/libp2p/{go-libp2p-core => go-libp2p/core}/transport/transport.go (93%) create mode 100644 vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/timer.go rename vendor/github.com/libp2p/{go-eventbus => go-libp2p/p2p/host/eventbus}/LICENSE-APACHE (100%) rename vendor/github.com/libp2p/{go-eventbus => go-libp2p/p2p/host/eventbus}/LICENSE-MIT (100%) rename vendor/github.com/libp2p/{go-eventbus => go-libp2p/p2p/host/eventbus}/basic.go (98%) rename vendor/github.com/libp2p/{go-eventbus => go-libp2p/p2p/host/eventbus}/opts.go (90%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/metrics.go (96%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/peerstore.go (79%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/pstoremem/addr_book.go (98%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/pstoremem/keybook.go (92%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/pstoremem/metadata.go (91%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/pstoremem/peerstore.go (94%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/pstoremem/protobook.go (97%) rename vendor/github.com/libp2p/{go-libp2p-peerstore => go-libp2p/p2p/host/peerstore}/pstoremem/sorting.go (100%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/README.md (58%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/allowlist.go (99%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/error.go (98%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/extapi.go (96%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/limit.go (87%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/limit_config_test.json (100%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/limit_defaults.go (89%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/metrics.go (96%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/rcmgr.go (99%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/scope.go (93%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/sys_not_unix.go (100%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/sys_unix.go (100%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/sys_windows.go (100%) rename vendor/github.com/libp2p/{go-libp2p-resource-manager => go-libp2p/p2p/host/resource-manager}/trace.go (99%) create mode 100644 vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dialer.go delete mode 100644 vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/multidialer.go delete mode 100644 vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/singledialer.go create mode 100644 vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session_transport.go create mode 100644 vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/options.go create mode 100644 vendor/github.com/libp2p/go-openssl/alloc.go create mode 100644 vendor/github.com/libp2p/go-openssl/version.json delete mode 100644 vendor/github.com/libp2p/go-yamux/v3/version.json rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/.gitignore (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/LICENSE (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/LICENSE-BSD (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/README.md (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/addr.go (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/const.go (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/deadline.go (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/mux.go (89%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/ping.go (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/session.go (90%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/spec.md (100%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/stream.go (96%) rename vendor/github.com/libp2p/go-yamux/{v3 => v4}/util.go (87%) create mode 100644 vendor/github.com/libp2p/go-yamux/v4/version.json delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/gen.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/qtls/go116.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/qtls/go117.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/byteinterval_linkedlist.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/gen.go create mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/linkedlist/README.md rename vendor/github.com/lucas-clemente/quic-go/internal/{ackhandler/packet_linkedlist.go => utils/linkedlist/linkedlist.go} (62%) delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/new_connection_id.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/newconnectionid_linkedlist.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/packet_interval.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/packetinterval_linkedlist.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/internal/utils/streamframe_interval.go create mode 100644 vendor/github.com/lucas-clemente/quic-go/logging/null_tracer.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/streams_map_generic_helper.go rename vendor/github.com/lucas-clemente/quic-go/{streams_map_incoming_uni.go => streams_map_incoming.go} (78%) delete mode 100644 vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go rename vendor/github.com/lucas-clemente/quic-go/{streams_map_outgoing_uni.go => streams_map_outgoing.go} (74%) delete mode 100644 vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go delete mode 100644 vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go create mode 100644 vendor/github.com/lucas-clemente/quic-go/zero_rtt_queue.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/README.md delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/alert.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/auth.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/cipher_suites.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/common.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/common_js.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/common_nojs.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/conn.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/handshake_client.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/handshake_client_tls13.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/handshake_messages.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/handshake_server.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/handshake_server_tls13.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/key_agreement.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/key_schedule.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/prf.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/ticket.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/tls.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-16/unsafe.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/README.md delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/alert.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/auth.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/cipher_suites.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/common.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/conn.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/cpu.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/cpu_other.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/handshake_client.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/handshake_client_tls13.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/handshake_messages.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/handshake_server.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/handshake_server_tls13.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/key_agreement.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/key_schedule.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/prf.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/ticket.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/tls.go delete mode 100644 vendor/github.com/marten-seemann/qtls-go1-17/unsafe.go rename vendor/github.com/{cheekybits/genny => mattn/go-pointer}/LICENSE (96%) create mode 100644 vendor/github.com/mattn/go-pointer/README.md create mode 100644 vendor/github.com/mattn/go-pointer/_example/callback.h create mode 100644 vendor/github.com/mattn/go-pointer/doc.go create mode 100644 vendor/github.com/mattn/go-pointer/pointer.go create mode 100644 vendor/github.com/multiformats/go-base32/version.json create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/get_pid.go create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go rename vendor/github.com/prometheus/client_golang/prometheus/{go_collector_go117.go => go_collector_latest.go} (53%) create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/num_threads.go create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go delete mode 100644 vendor/github.com/prometheus/procfs/fixtures.ttar rename vendor/github.com/prometheus/procfs/{xfrm.go => net_xfrm.go} (96%) create mode 100644 vendor/github.com/prometheus/procfs/proc_cgroups.go create mode 100644 vendor/github.com/prometheus/procfs/proc_netstat.go create mode 100644 vendor/github.com/prometheus/procfs/proc_snmp.go create mode 100644 vendor/github.com/prometheus/procfs/proc_snmp6.go create mode 100644 vendor/github.com/prometheus/procfs/proc_sys.go create mode 100644 vendor/github.com/prometheus/procfs/softirqs.go delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/.gitignore delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/LICENSE delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/README.md delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/cleaner.go delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/client.go delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/discovery.go delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.pb.go delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.proto delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/proto.go delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/storage.go delete mode 100644 vendor/github.com/status-im/go-waku-rendezvous/svc.go delete mode 100644 vendor/github.com/status-im/go-waku/waku/persistence/rendezvous.go rename vendor/github.com/{status-im => waku-org}/go-discover/COPYING.LESSER (100%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/common.go (82%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/lookup.go (99%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/node.go (100%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/ntp.go (98%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/table.go (99%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/v4_udp.go (98%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/v4wire/v4wire.go (95%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/v5_udp.go (98%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/v5wire/crypto.go (100%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/v5wire/encoding.go (96%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/v5wire/msg.go (91%) rename vendor/github.com/{status-im => waku-org}/go-discover/discover/v5wire/session.go (100%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/LICENSE (100%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/librln.h (90%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/link.go (100%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/resources/bindata.go (100%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/resources/doc.go (100%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/rln.go (92%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/serialize.go (100%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/types.go (95%) rename vendor/github.com/{status-im => waku-org}/go-zerokit-rln/rln/utils.go (100%) create mode 100644 vendor/github.com/waku-org/noise/CONTRIBUTING.md rename vendor/github.com/{marten-seemann/qtls-go1-17 => waku-org/noise}/LICENSE (88%) create mode 100644 vendor/github.com/waku-org/noise/README.md create mode 100644 vendor/github.com/waku-org/noise/cipher_suite.go create mode 100644 vendor/github.com/waku-org/noise/hkdf.go create mode 100644 vendor/github.com/waku-org/noise/patterns.go create mode 100644 vendor/github.com/waku-org/noise/state.go create mode 100644 vendor/github.com/waku-org/noise/vectors.txt create mode 100644 vendor/go.uber.org/atomic/float32.go create mode 100644 vendor/go.uber.org/atomic/float32_ext.go create mode 100644 vendor/go.uber.org/atomic/pointer_go118.go create mode 100644 vendor/go.uber.org/atomic/pointer_go119.go create mode 100644 vendor/go.uber.org/zap/internal/level_enabler.go rename vendor/{github.com/marten-seemann/qtls-go1-16 => golang.org/x/exp}/LICENSE (100%) create mode 100644 vendor/golang.org/x/exp/PATENTS create mode 100644 vendor/golang.org/x/exp/constraints/constraints.go create mode 100644 vendor/golang.org/x/mod/modfile/print.go create mode 100644 vendor/golang.org/x/mod/modfile/read.go create mode 100644 vendor/golang.org/x/mod/modfile/rule.go create mode 100644 vendor/golang.org/x/mod/modfile/work.go delete mode 100644 vendor/golang.org/x/net/AUTHORS delete mode 100644 vendor/golang.org/x/net/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go rename vendor/golang.org/x/net/internal/socket/{zsys_darwin_arm.go => zsys_freebsd_riscv64.go} (79%) create mode 100644 vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go create mode 100644 vendor/golang.org/x/net/route/zsys_freebsd_riscv64.go delete mode 100644 vendor/golang.org/x/sync/AUTHORS delete mode 100644 vendor/golang.org/x/sync/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/text/AUTHORS delete mode 100644 vendor/golang.org/x/text/CONTRIBUTORS delete mode 100644 vendor/golang.org/x/text/language/go1_1.go delete mode 100644 vendor/golang.org/x/text/language/go1_2.go delete mode 100644 vendor/golang.org/x/tools/AUTHORS delete mode 100644 vendor/golang.org/x/tools/CONTRIBUTORS create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go create mode 100644 vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/codes.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/doc.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/flags.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/support.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/sync.go create mode 100644 vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go delete mode 100644 vendor/google.golang.org/protobuf/AUTHORS delete mode 100644 vendor/google.golang.org/protobuf/CONTRIBUTORS diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go b/vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go index efde8d6a8..f85baba8c 100644 --- a/vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go @@ -39,3 +39,18 @@ type CurveParams = secp.CurveParams func Params() *CurveParams { return secp.Params() } + +// Generator returns the public key at the Generator Point. +func Generator() *PublicKey { + var ( + result JacobianPoint + k secp.ModNScalar + ) + + k.SetInt(1) + ScalarBaseMultNonConst(&k, &result) + + result.ToAffine() + + return NewPublicKey(&result.X, &result.Y) +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/curve.go b/vendor/github.com/btcsuite/btcd/btcec/v2/curve.go index 5224e35c8..70a9229f9 100644 --- a/vendor/github.com/btcsuite/btcd/btcec/v2/curve.go +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/curve.go @@ -4,6 +4,8 @@ package btcec import ( + "fmt" + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" ) @@ -11,6 +13,9 @@ import ( // Jacobian projective coordinates and thus represents a point on the curve. type JacobianPoint = secp.JacobianPoint +// infinityPoint is the jacobian representation of the point at infinity. +var infinityPoint JacobianPoint + // MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z // coordinates. func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint { @@ -61,3 +66,50 @@ func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { secp.ScalarMultNonConst(k, point, result) } + +// ParseJacobian parses a byte slice point as a secp.Publickey and returns the +// pubkey as a JacobianPoint. If the nonce is a zero slice, the infinityPoint +// is returned. +func ParseJacobian(point []byte) (JacobianPoint, error) { + var result JacobianPoint + + if len(point) != 33 { + str := fmt.Sprintf("invalid nonce: invalid length: %v", + len(point)) + return JacobianPoint{}, makeError(secp.ErrPubKeyInvalidLen, str) + } + + if point[0] == 0x00 { + return infinityPoint, nil + } + + noncePk, err := secp.ParsePubKey(point) + if err != nil { + return JacobianPoint{}, err + } + noncePk.AsJacobian(&result) + + return result, nil +} + +// JacobianToByteSlice converts the passed JacobianPoint to a Pubkey +// and serializes that to a byte slice. If the JacobianPoint is the infinity +// point, a zero slice is returned. +func JacobianToByteSlice(point JacobianPoint) []byte { + if point.X == infinityPoint.X && point.Y == infinityPoint.Y { + return make([]byte, 33) + } + + point.ToAffine() + + return NewPublicKey( + &point.X, &point.Y, + ).SerializeCompressed() +} + +// GeneratorJacobian sets the passed JacobianPoint to the Generator Point. +func GeneratorJacobian(jacobian *JacobianPoint) { + var k ModNScalar + k.SetInt(1) + ScalarBaseMultNonConst(&k, jacobian) +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/error.go b/vendor/github.com/btcsuite/btcd/btcec/v2/error.go index 81ca2b044..df6ec678a 100644 --- a/vendor/github.com/btcsuite/btcd/btcec/v2/error.go +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/error.go @@ -17,3 +17,8 @@ type Error = secp.Error // errors.As, so the caller can directly check against an error kind when // determining the reason for an error. type ErrorKind = secp.ErrorKind + +// makeError creates an secp.Error given a set of arguments. +func makeError(kind ErrorKind, desc string) Error { + return Error{Err: kind, Description: desc} +} diff --git a/vendor/github.com/cheekybits/genny/.gitignore b/vendor/github.com/cheekybits/genny/.gitignore deleted file mode 100644 index c62d148c2..000000000 --- a/vendor/github.com/cheekybits/genny/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Compiled Object files, Static and Dynamic libs (Shared Objects) -*.o -*.a -*.so - -# Folders -_obj -_test - -# Architecture specific extensions/prefixes -*.[568vq] -[568vq].out - -*.cgo1.go -*.cgo2.c -_cgo_defun.c -_cgo_gotypes.go -_cgo_export.* - -_testmain.go - -*.exe -*.test -*.prof - -genny diff --git a/vendor/github.com/cheekybits/genny/.travis.yml b/vendor/github.com/cheekybits/genny/.travis.yml deleted file mode 100644 index 78ba5f2d1..000000000 --- a/vendor/github.com/cheekybits/genny/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: go - -go: - - 1.7 - - 1.8 - - 1.9 diff --git a/vendor/github.com/cheekybits/genny/README.md b/vendor/github.com/cheekybits/genny/README.md deleted file mode 100644 index 64a28ac72..000000000 --- a/vendor/github.com/cheekybits/genny/README.md +++ /dev/null @@ -1,245 +0,0 @@ -# genny - Generics for Go - -[![Build Status](https://travis-ci.org/cheekybits/genny.svg?branch=master)](https://travis-ci.org/cheekybits/genny) [![GoDoc](https://godoc.org/github.com/cheekybits/genny/parse?status.png)](http://godoc.org/github.com/cheekybits/genny/parse) - -Install: - -``` -go get github.com/cheekybits/genny -``` - -===== - -(pron. Jenny) by Mat Ryer ([@matryer](https://twitter.com/matryer)) and Tyler Bunnell ([@TylerJBunnell](https://twitter.com/TylerJBunnell)). - -Until the Go core team include support for [generics in Go](http://golang.org/doc/faq#generics), `genny` is a code-generation generics solution. It allows you write normal buildable and testable Go code which, when processed by the `genny gen` tool, will replace the generics with specific types. - - * Generic code is valid Go code - * Generic code compiles and can be tested - * Use `stdin` and `stdout` or specify in and out files - * Supports Go 1.4's [go generate](http://tip.golang.org/doc/go1.4#gogenerate) - * Multiple specific types will generate every permutation - * Use `BUILTINS` and `NUMBERS` wildtype to generate specific code for all built-in (and number) Go types - * Function names and comments also get updated - -## Library - -We have started building a [library of common things](https://github.com/cheekybits/gennylib), and you can use `genny get` to generate the specific versions you need. - -For example: `genny get maps/concurrentmap.go "KeyType=BUILTINS ValueType=BUILTINS"` will print out generated code for all types for a concurrent map. Any file in the library may be generated locally in this way using all the same options given to `genny gen`. - -## Usage - -``` -genny [{flags}] gen "{types}" - -gen - generates type specific code from generic code. -get - fetch a generic template from the online library and gen it. - -{flags} - (optional) Command line flags (see below) -{types} - (required) Specific types for each generic type in the source -{types} format: {generic}={specific}[,another][ {generic2}={specific2}] - -Examples: - Generic=Specific - Generic1=Specific1 Generic2=Specific2 - Generic1=Specific1,Specific2 Generic2=Specific3,Specific4 - -Flags: - -in="": file to parse instead of stdin - -out="": file to save output to instead of stdout - -pkg="": package name for generated files -``` - - * Comma separated type lists will generate code for each type - -### Flags - - * `-in` - specify the input file (rather than using stdin) - * `-out` - specify the output file (rather than using stdout) - -### go generate - -To use Go 1.4's `go generate` capability, insert the following comment in your source code file: - -``` -//go:generate genny -in=$GOFILE -out=gen-$GOFILE gen "KeyType=string,int ValueType=string,int" -``` - - * Start the line with `//go:generate ` - * Use the `-in` and `-out` flags to specify the files to work on - * Use the `genny` command as usual after the flags - -Now, running `go generate` (in a shell) for the package will cause the generic versions of the files to be generated. - - * The output file will be overwritten, so it's safe to call `go generate` many times - * Use `$GOFILE` to refer to the current file - * The `//go:generate` line will be removed from the output - -To see a real example of how to use `genny` with `go generate`, look in the [example/go-generate directory](https://github.com/cheekybits/genny/tree/master/examples/go-generate). - -## How it works - -Define your generic types using the special `generic.Type` placeholder type: - -```go -type KeyType generic.Type -type ValueType generic.Type -``` - - * You can use as many as you like - * Give them meaningful names - -Then write the generic code referencing the types as your normally would: - -```go -func SetValueTypeForKeyType(key KeyType, value ValueType) { /* ... */ } -``` - - * Generic type names will also be replaced in comments and function names (see Real example below) - -Since `generic.Type` is a real Go type, your code will compile, and you can even write unit tests against your generic code. - -#### Generating specific versions - -Pass the file through the `genny gen` tool with the specific types as the argument: - -``` -cat generic.go | genny gen "KeyType=string ValueType=interface{}" -``` - -The output will be the complete Go source file with the generic types replaced with the types specified in the arguments. - -## Real example - -Given [this generic Go code](https://github.com/cheekybits/genny/tree/master/examples/queue) which compiles and is tested: - -```go -package queue - -import "github.com/cheekybits/genny/generic" - -// NOTE: this is how easy it is to define a generic type -type Something generic.Type - -// SomethingQueue is a queue of Somethings. -type SomethingQueue struct { - items []Something -} - -func NewSomethingQueue() *SomethingQueue { - return &SomethingQueue{items: make([]Something, 0)} -} -func (q *SomethingQueue) Push(item Something) { - q.items = append(q.items, item) -} -func (q *SomethingQueue) Pop() Something { - item := q.items[0] - q.items = q.items[1:] - return item -} -``` - -When `genny gen` is invoked like this: - -``` -cat source.go | genny gen "Something=string" -``` - -It outputs: - -```go -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package queue - -// StringQueue is a queue of Strings. -type StringQueue struct { - items []string -} - -func NewStringQueue() *StringQueue { - return &StringQueue{items: make([]string, 0)} -} -func (q *StringQueue) Push(item string) { - q.items = append(q.items, item) -} -func (q *StringQueue) Pop() string { - item := q.items[0] - q.items = q.items[1:] - return item -} -``` - -To get a _something_ for every built-in Go type plus one of your own types, you could run: - -``` -cat source.go | genny gen "Something=BUILTINS,*MyType" -``` - -#### More examples - -Check out the [test code files](https://github.com/cheekybits/genny/tree/master/parse/test) for more real examples. - -## Writing test code - -Once you have defined a generic type with some code worth testing: - -```go -package slice - -import ( - "log" - "reflect" - - "github.com/stretchr/gogen/generic" -) - -type MyType generic.Type - -func EnsureMyTypeSlice(objectOrSlice interface{}) []MyType { - log.Printf("%v", reflect.TypeOf(objectOrSlice)) - switch obj := objectOrSlice.(type) { - case []MyType: - log.Println(" returning it untouched") - return obj - case MyType: - log.Println(" wrapping in slice") - return []MyType{obj} - default: - panic("ensure slice needs MyType or []MyType") - } -} -``` - -You can treat it like any normal Go type in your test code: - -```go -func TestEnsureMyTypeSlice(t *testing.T) { - - myType := new(MyType) - slice := EnsureMyTypeSlice(myType) - if assert.NotNil(t, slice) { - assert.Equal(t, slice[0], myType) - } - - slice = EnsureMyTypeSlice(slice) - log.Printf("%#v", slice[0]) - if assert.NotNil(t, slice) { - assert.Equal(t, slice[0], myType) - } - -} -``` - -### Understanding what `generic.Type` is - -Because `generic.Type` is an empty interface type (literally `interface{}`) every other type will be considered to be a `generic.Type` if you are switching on the type of an object. Of course, once the specific versions are generated, this issue goes away but it's worth knowing when you are writing your tests against generic code. - -### Contributions - - * See the [API documentation for the parse package](http://godoc.org/github.com/cheekybits/genny/parse) - * Please do TDD - * All input welcome diff --git a/vendor/github.com/cheekybits/genny/doc.go b/vendor/github.com/cheekybits/genny/doc.go deleted file mode 100644 index 4c31e22bc..000000000 --- a/vendor/github.com/cheekybits/genny/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package main is the command line tool for Genny. -package main diff --git a/vendor/github.com/cheekybits/genny/generic/doc.go b/vendor/github.com/cheekybits/genny/generic/doc.go deleted file mode 100644 index 3bd6c869c..000000000 --- a/vendor/github.com/cheekybits/genny/generic/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package generic contains the generic marker types. -package generic diff --git a/vendor/github.com/cheekybits/genny/generic/generic.go b/vendor/github.com/cheekybits/genny/generic/generic.go deleted file mode 100644 index 04a2306cb..000000000 --- a/vendor/github.com/cheekybits/genny/generic/generic.go +++ /dev/null @@ -1,13 +0,0 @@ -package generic - -// Type is the placeholder type that indicates a generic value. -// When genny is executed, variables of this type will be replaced with -// references to the specific types. -// var GenericType generic.Type -type Type interface{} - -// Number is the placehoder type that indiccates a generic numerical value. -// When genny is executed, variables of this type will be replaced with -// references to the specific types. -// var GenericType generic.Number -type Number float64 diff --git a/vendor/github.com/cheekybits/genny/main.go b/vendor/github.com/cheekybits/genny/main.go deleted file mode 100644 index fe06a6c03..000000000 --- a/vendor/github.com/cheekybits/genny/main.go +++ /dev/null @@ -1,154 +0,0 @@ -package main - -import ( - "bytes" - "flag" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "strings" - - "github.com/cheekybits/genny/out" - "github.com/cheekybits/genny/parse" -) - -/* - - source | genny gen [-in=""] [-out=""] [-pkg=""] "KeyType=string,int ValueType=string,int" - -*/ - -const ( - _ = iota - exitcodeInvalidArgs - exitcodeInvalidTypeSet - exitcodeStdinFailed - exitcodeGenFailed - exitcodeGetFailed - exitcodeSourceFileInvalid - exitcodeDestFileFailed -) - -func main() { - var ( - in = flag.String("in", "", "file to parse instead of stdin") - out = flag.String("out", "", "file to save output to instead of stdout") - pkgName = flag.String("pkg", "", "package name for generated files") - prefix = "https://github.com/metabition/gennylib/raw/master/" - ) - flag.Parse() - args := flag.Args() - - if len(args) < 2 { - usage() - os.Exit(exitcodeInvalidArgs) - } - - if strings.ToLower(args[0]) != "gen" && strings.ToLower(args[0]) != "get" { - usage() - os.Exit(exitcodeInvalidArgs) - } - - // parse the typesets - var setsArg = args[1] - if strings.ToLower(args[0]) == "get" { - setsArg = args[2] - } - typeSets, err := parse.TypeSet(setsArg) - if err != nil { - fatal(exitcodeInvalidTypeSet, err) - } - - outWriter := newWriter(*out) - - if strings.ToLower(args[0]) == "get" { - if len(args) != 3 { - fmt.Println("not enough arguments to get") - usage() - os.Exit(exitcodeInvalidArgs) - } - r, err := http.Get(prefix + args[1]) - if err != nil { - fatal(exitcodeGetFailed, err) - } - b, err := ioutil.ReadAll(r.Body) - if err != nil { - fatal(exitcodeGetFailed, err) - } - r.Body.Close() - br := bytes.NewReader(b) - err = gen(*in, *pkgName, br, typeSets, outWriter) - } else if len(*in) > 0 { - var file *os.File - file, err = os.Open(*in) - if err != nil { - fatal(exitcodeSourceFileInvalid, err) - } - defer file.Close() - err = gen(*in, *pkgName, file, typeSets, outWriter) - } else { - var source []byte - source, err = ioutil.ReadAll(os.Stdin) - if err != nil { - fatal(exitcodeStdinFailed, err) - } - reader := bytes.NewReader(source) - err = gen("stdin", *pkgName, reader, typeSets, outWriter) - } - - // do the work - if err != nil { - fatal(exitcodeGenFailed, err) - } - -} - -func usage() { - fmt.Fprintln(os.Stderr, `usage: genny [{flags}] gen "{types}" - -gen - generates type specific code from generic code. -get - fetch a generic template from the online library and gen it. - -{flags} - (optional) Command line flags (see below) -{types} - (required) Specific types for each generic type in the source -{types} format: {generic}={specific}[,another][ {generic2}={specific2}] - -Examples: - Generic=Specific - Generic1=Specific1 Generic2=Specific2 - Generic1=Specific1,Specific2 Generic2=Specific3,Specific4 - -Flags:`) - flag.PrintDefaults() -} - -func newWriter(fileName string) io.Writer { - if fileName == "" { - return os.Stdout - } - lf := &out.LazyFile{FileName: fileName} - defer lf.Close() - return lf -} - -func fatal(code int, a ...interface{}) { - fmt.Println(a...) - os.Exit(code) -} - -// gen performs the generic generation. -func gen(filename, pkgName string, in io.ReadSeeker, typesets []map[string]string, out io.Writer) error { - - var output []byte - var err error - - output, err = parse.Generics(filename, pkgName, in, typesets) - if err != nil { - return err - } - - out.Write(output) - return nil -} diff --git a/vendor/github.com/cheekybits/genny/out/lazy_file.go b/vendor/github.com/cheekybits/genny/out/lazy_file.go deleted file mode 100644 index 7c8815f5f..000000000 --- a/vendor/github.com/cheekybits/genny/out/lazy_file.go +++ /dev/null @@ -1,38 +0,0 @@ -package out - -import ( - "os" - "path" -) - -// LazyFile is an io.WriteCloser which defers creation of the file it is supposed to write in -// till the first call to its write function in order to prevent creation of file, if no write -// is supposed to happen. -type LazyFile struct { - // FileName is path to the file to which genny will write. - FileName string - file *os.File -} - -// Close closes the file if it is created. Returns nil if no file is created. -func (lw *LazyFile) Close() error { - if lw.file != nil { - return lw.file.Close() - } - return nil -} - -// Write writes to the specified file and creates the file first time it is called. -func (lw *LazyFile) Write(p []byte) (int, error) { - if lw.file == nil { - err := os.MkdirAll(path.Dir(lw.FileName), 0755) - if err != nil { - return 0, err - } - lw.file, err = os.Create(lw.FileName) - if err != nil { - return 0, err - } - } - return lw.file.Write(p) -} diff --git a/vendor/github.com/cheekybits/genny/parse/builtins.go b/vendor/github.com/cheekybits/genny/parse/builtins.go deleted file mode 100644 index e02995444..000000000 --- a/vendor/github.com/cheekybits/genny/parse/builtins.go +++ /dev/null @@ -1,41 +0,0 @@ -package parse - -// Builtins contains a slice of all built-in Go types. -var Builtins = []string{ - "bool", - "byte", - "complex128", - "complex64", - "error", - "float32", - "float64", - "int", - "int16", - "int32", - "int64", - "int8", - "rune", - "string", - "uint", - "uint16", - "uint32", - "uint64", - "uint8", - "uintptr", -} - -// Numbers contains a slice of all built-in number types. -var Numbers = []string{ - "float32", - "float64", - "int", - "int16", - "int32", - "int64", - "int8", - "uint", - "uint16", - "uint32", - "uint64", - "uint8", -} diff --git a/vendor/github.com/cheekybits/genny/parse/doc.go b/vendor/github.com/cheekybits/genny/parse/doc.go deleted file mode 100644 index 1be4fed8b..000000000 --- a/vendor/github.com/cheekybits/genny/parse/doc.go +++ /dev/null @@ -1,14 +0,0 @@ -// Package parse contains the generic code generation capabilities -// that power genny. -// -// genny gen "{types}" -// -// gen - generates type specific code (to stdout) from generic code (via stdin) -// -// {types} - (required) Specific types for each generic type in the source -// {types} format: {generic}={specific}[,another][ {generic2}={specific2}] -// Examples: -// Generic=Specific -// Generic1=Specific1 Generic2=Specific2 -// Generic1=Specific1,Specific2 Generic2=Specific3,Specific4 -package parse diff --git a/vendor/github.com/cheekybits/genny/parse/errors.go b/vendor/github.com/cheekybits/genny/parse/errors.go deleted file mode 100644 index ab812bf90..000000000 --- a/vendor/github.com/cheekybits/genny/parse/errors.go +++ /dev/null @@ -1,47 +0,0 @@ -package parse - -import ( - "errors" -) - -// errMissingSpecificType represents an error when a generic type is not -// satisfied by a specific type. -type errMissingSpecificType struct { - GenericType string -} - -// Error gets a human readable string describing this error. -func (e errMissingSpecificType) Error() string { - return "Missing specific type for '" + e.GenericType + "' generic type" -} - -// errImports represents an error from goimports. -type errImports struct { - Err error -} - -// Error gets a human readable string describing this error. -func (e errImports) Error() string { - return "Failed to goimports the generated code: " + e.Err.Error() -} - -// errSource represents an error with the source file. -type errSource struct { - Err error -} - -// Error gets a human readable string describing this error. -func (e errSource) Error() string { - return "Failed to parse source file: " + e.Err.Error() -} - -type errBadTypeArgs struct { - Message string - Arg string -} - -func (e errBadTypeArgs) Error() string { - return "\"" + e.Arg + "\" is bad: " + e.Message -} - -var errMissingTypeInformation = errors.New("No type arguments were specified and no \"// +gogen\" tag was found in the source.") diff --git a/vendor/github.com/cheekybits/genny/parse/parse.go b/vendor/github.com/cheekybits/genny/parse/parse.go deleted file mode 100644 index 08eb48b11..000000000 --- a/vendor/github.com/cheekybits/genny/parse/parse.go +++ /dev/null @@ -1,298 +0,0 @@ -package parse - -import ( - "bufio" - "bytes" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "io" - "os" - "strings" - "unicode" - - "golang.org/x/tools/imports" -) - -var header = []byte(` - -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -`) - -var ( - packageKeyword = []byte("package") - importKeyword = []byte("import") - openBrace = []byte("(") - closeBrace = []byte(")") - genericPackage = "generic" - genericType = "generic.Type" - genericNumber = "generic.Number" - linefeed = "\r\n" -) -var unwantedLinePrefixes = [][]byte{ - []byte("//go:generate genny "), -} - -func subIntoLiteral(lit, typeTemplate, specificType string) string { - if lit == typeTemplate { - return specificType - } - if !strings.Contains(lit, typeTemplate) { - return lit - } - specificLg := wordify(specificType, true) - specificSm := wordify(specificType, false) - result := strings.Replace(lit, typeTemplate, specificLg, -1) - if strings.HasPrefix(result, specificLg) && !isExported(lit) { - return strings.Replace(result, specificLg, specificSm, 1) - } - return result -} - -func subTypeIntoComment(line, typeTemplate, specificType string) string { - var subbed string - for _, w := range strings.Fields(line) { - subbed = subbed + subIntoLiteral(w, typeTemplate, specificType) + " " - } - return subbed -} - -// Does the heavy lifting of taking a line of our code and -// sbustituting a type into there for our generic type -func subTypeIntoLine(line, typeTemplate, specificType string) string { - src := []byte(line) - var s scanner.Scanner - fset := token.NewFileSet() - file := fset.AddFile("", fset.Base(), len(src)) - s.Init(file, src, nil, scanner.ScanComments) - output := "" - for { - _, tok, lit := s.Scan() - if tok == token.EOF { - break - } else if tok == token.COMMENT { - subbed := subTypeIntoComment(lit, typeTemplate, specificType) - output = output + subbed + " " - } else if tok.IsLiteral() { - subbed := subIntoLiteral(lit, typeTemplate, specificType) - output = output + subbed + " " - } else { - output = output + tok.String() + " " - } - } - return output -} - -// typeSet looks like "KeyType: int, ValueType: string" -func generateSpecific(filename string, in io.ReadSeeker, typeSet map[string]string) ([]byte, error) { - - // ensure we are at the beginning of the file - in.Seek(0, os.SEEK_SET) - - // parse the source file - fs := token.NewFileSet() - file, err := parser.ParseFile(fs, filename, in, 0) - if err != nil { - return nil, &errSource{Err: err} - } - - // make sure every generic.Type is represented in the types - // argument. - for _, decl := range file.Decls { - switch it := decl.(type) { - case *ast.GenDecl: - for _, spec := range it.Specs { - ts, ok := spec.(*ast.TypeSpec) - if !ok { - continue - } - switch tt := ts.Type.(type) { - case *ast.SelectorExpr: - if name, ok := tt.X.(*ast.Ident); ok { - if name.Name == genericPackage { - if _, ok := typeSet[ts.Name.Name]; !ok { - return nil, &errMissingSpecificType{GenericType: ts.Name.Name} - } - } - } - } - } - } - } - - in.Seek(0, os.SEEK_SET) - - var buf bytes.Buffer - - comment := "" - scanner := bufio.NewScanner(in) - for scanner.Scan() { - - line := scanner.Text() - - // does this line contain generic.Type? - if strings.Contains(line, genericType) || strings.Contains(line, genericNumber) { - comment = "" - continue - } - - for t, specificType := range typeSet { - if strings.Contains(line, t) { - newLine := subTypeIntoLine(line, t, specificType) - line = newLine - } - } - - if comment != "" { - buf.WriteString(makeLine(comment)) - comment = "" - } - - // is this line a comment? - // TODO: should we handle /* */ comments? - if strings.HasPrefix(line, "//") { - // record this line to print later - comment = line - continue - } - - // write the line - buf.WriteString(makeLine(line)) - } - - // write it out - return buf.Bytes(), nil -} - -// Generics parses the source file and generates the bytes replacing the -// generic types for the keys map with the specific types (its value). -func Generics(filename, pkgName string, in io.ReadSeeker, typeSets []map[string]string) ([]byte, error) { - - totalOutput := header - - for _, typeSet := range typeSets { - - // generate the specifics - parsed, err := generateSpecific(filename, in, typeSet) - if err != nil { - return nil, err - } - - totalOutput = append(totalOutput, parsed...) - - } - - // clean up the code line by line - packageFound := false - insideImportBlock := false - var cleanOutputLines []string - scanner := bufio.NewScanner(bytes.NewReader(totalOutput)) - for scanner.Scan() { - - // end of imports block? - if insideImportBlock { - if bytes.HasSuffix(scanner.Bytes(), closeBrace) { - insideImportBlock = false - } - continue - } - - if bytes.HasPrefix(scanner.Bytes(), packageKeyword) { - if packageFound { - continue - } else { - packageFound = true - } - } else if bytes.HasPrefix(scanner.Bytes(), importKeyword) { - if bytes.HasSuffix(scanner.Bytes(), openBrace) { - insideImportBlock = true - } - continue - } - - // check all unwantedLinePrefixes - and skip them - skipline := false - for _, prefix := range unwantedLinePrefixes { - if bytes.HasPrefix(scanner.Bytes(), prefix) { - skipline = true - continue - } - } - - if skipline { - continue - } - - cleanOutputLines = append(cleanOutputLines, makeLine(scanner.Text())) - } - - cleanOutput := strings.Join(cleanOutputLines, "") - - output := []byte(cleanOutput) - var err error - - // change package name - if pkgName != "" { - output = changePackage(bytes.NewReader([]byte(output)), pkgName) - } - // fix the imports - output, err = imports.Process(filename, output, nil) - if err != nil { - return nil, &errImports{Err: err} - } - - return output, nil -} - -func makeLine(s string) string { - return fmt.Sprintln(strings.TrimRight(s, linefeed)) -} - -// isAlphaNumeric gets whether the rune is alphanumeric or _. -func isAlphaNumeric(r rune) bool { - return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) -} - -// wordify turns a type into a nice word for function and type -// names etc. -func wordify(s string, exported bool) string { - s = strings.TrimRight(s, "{}") - s = strings.TrimLeft(s, "*&") - s = strings.Replace(s, ".", "", -1) - if !exported { - return s - } - return strings.ToUpper(string(s[0])) + s[1:] -} - -func changePackage(r io.Reader, pkgName string) []byte { - var out bytes.Buffer - sc := bufio.NewScanner(r) - done := false - - for sc.Scan() { - s := sc.Text() - - if !done && strings.HasPrefix(s, "package") { - parts := strings.Split(s, " ") - parts[1] = pkgName - s = strings.Join(parts, " ") - done = true - } - - fmt.Fprintln(&out, s) - } - return out.Bytes() -} - -func isExported(lit string) bool { - if len(lit) == 0 { - return false - } - return unicode.IsUpper(rune(lit[0])) -} diff --git a/vendor/github.com/cheekybits/genny/parse/typesets.go b/vendor/github.com/cheekybits/genny/parse/typesets.go deleted file mode 100644 index c30b97289..000000000 --- a/vendor/github.com/cheekybits/genny/parse/typesets.go +++ /dev/null @@ -1,89 +0,0 @@ -package parse - -import "strings" - -const ( - typeSep = " " - keyValueSep = "=" - valuesSep = "," - builtins = "BUILTINS" - numbers = "NUMBERS" -) - -// TypeSet turns a type string into a []map[string]string -// that can be given to parse.Generics for it to do its magic. -// -// Acceptable args are: -// -// Person=man -// Person=man Animal=dog -// Person=man Animal=dog Animal2=cat -// Person=man,woman Animal=dog,cat -// Person=man,woman,child Animal=dog,cat Place=london,paris -func TypeSet(arg string) ([]map[string]string, error) { - - types := make(map[string][]string) - var keys []string - for _, pair := range strings.Split(arg, typeSep) { - segs := strings.Split(pair, keyValueSep) - if len(segs) != 2 { - return nil, &errBadTypeArgs{Arg: arg, Message: "Generic=Specific expected"} - } - key := segs[0] - keys = append(keys, key) - types[key] = make([]string, 0) - for _, t := range strings.Split(segs[1], valuesSep) { - if t == builtins { - types[key] = append(types[key], Builtins...) - } else if t == numbers { - types[key] = append(types[key], Numbers...) - } else { - types[key] = append(types[key], t) - } - } - } - - cursors := make(map[string]int) - for _, key := range keys { - cursors[key] = 0 - } - - outChan := make(chan map[string]string) - go func() { - buildTypeSet(keys, 0, cursors, types, outChan) - close(outChan) - }() - - var typeSets []map[string]string - for typeSet := range outChan { - typeSets = append(typeSets, typeSet) - } - - return typeSets, nil - -} - -func buildTypeSet(keys []string, keyI int, cursors map[string]int, types map[string][]string, out chan<- map[string]string) { - key := keys[keyI] - for cursors[key] < len(types[key]) { - if keyI < len(keys)-1 { - buildTypeSet(keys, keyI+1, copycursors(cursors), types, out) - } else { - // build the typeset for this combination - ts := make(map[string]string) - for k, vals := range types { - ts[k] = vals[cursors[k]] - } - out <- ts - } - cursors[key]++ - } -} - -func copycursors(source map[string]int) map[string]int { - copy := make(map[string]int) - for k, v := range source { - copy[k] = v - } - return copy -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go index cff5af1a6..147f756fe 100644 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go @@ -176,6 +176,11 @@ func (c *Conn) Close() { c.sigconn.Close() } +// Connected returns whether conn is connected +func (c *Conn) Connected() bool { + return c.sysconn.Connected() && c.sigconn.Connected() +} + // NewConnection establishes a connection to a bus using a caller-supplied function. // This allows connecting to remote buses through a user-supplied mechanism. // The supplied function may be called multiple times, and should return independent connections. diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go index fa04afc70..074148cb4 100644 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go +++ b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go @@ -417,6 +417,29 @@ func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) { return status, nil } +// GetUnitByPID returns the unit object path of the unit a process ID +// belongs to. It takes a UNIX PID and returns the object path. The PID must +// refer to an existing system process +func (c *Conn) GetUnitByPID(ctx context.Context, pid uint32) (dbus.ObjectPath, error) { + var result dbus.ObjectPath + + err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.GetUnitByPID", 0, pid).Store(&result) + + return result, err +} + +// GetUnitNameByPID returns the name of the unit a process ID belongs to. It +// takes a UNIX PID and returns the object path. The PID must refer to an +// existing system process +func (c *Conn) GetUnitNameByPID(ctx context.Context, pid uint32) (string, error) { + path, err := c.GetUnitByPID(ctx, pid) + if err != nil { + return "", err + } + + return unitName(path), nil +} + // Deprecated: use ListUnitsContext instead. func (c *Conn) ListUnits() ([]UnitStatus, error) { return c.ListUnitsContext(context.Background()) @@ -828,3 +851,14 @@ func (c *Conn) listJobsInternal(ctx context.Context) ([]JobStatus, error) { return status, nil } + +// Freeze the cgroup associated with the unit. +// Note that FreezeUnit and ThawUnit are only supported on systems running with cgroup v2. +func (c *Conn) FreezeUnit(ctx context.Context, unit string) error { + return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.FreezeUnit", 0, unit).Store() +} + +// Unfreeze the cgroup associated with the unit. +func (c *Conn) ThawUnit(ctx context.Context, unit string) error { + return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ThawUnit", 0, unit).Store() +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go index ca4be1218..bb0b41fda 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go @@ -1,5 +1,5 @@ // Copyright (c) 2015 The btcsuite developers -// Copyright (c) 2015-2021 The Decred developers +// Copyright (c) 2015-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -8,4 +8,11 @@ package secp256k1 // Auto-generated file (see genprecomps.go) // DO NOT EDIT -var compressedBytePoints = "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" +var compressedBytePoints = "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" + +// Set accessor to a real function. +func init() { + compressedBytePointsFn = func() string { + return compressedBytePoints + } +} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go index e8620608f..c9d47f307 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2021 The Decred developers +// Copyright (c) 2015-2022 The Decred developers // Copyright 2013-2014 The btcsuite developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -7,7 +7,7 @@ package secp256k1 import ( "encoding/hex" - "math/big" + "math/bits" ) // References: @@ -18,6 +18,9 @@ import ( // // [BRID]: On Binary Representations of Integers with Digits -1, 0, 1 // (Prodinger, Helmut) +// +// [STWS]: Secure-TWS: Authenticating Node to Multi-user Communication in +// Shared Sensor Networks (Oliveira, Leonardo B. et al) // All group operations are performed using Jacobian coordinates. For a given // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) @@ -39,29 +42,59 @@ func hexToFieldVal(s string) *FieldVal { return &f } -var ( - // Next 6 constants are from Hal Finney's bitcointalk.org post: - // https://bitcointalk.org/index.php?topic=3238.msg45565#msg45565 - // May he rest in peace. - // - // They have also been independently derived from the code in the - // EndomorphismVectors function in genstatics.go. - endomorphismLambda = fromHex("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72") - endomorphismBeta = hexToFieldVal("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee") - endomorphismA1 = fromHex("3086d221a7d46bcde86c90e49284eb15") - endomorphismB1 = fromHex("-e4437ed6010e88286f547fa90abfe4c3") - endomorphismA2 = fromHex("114ca50f7a8e2f3f657c1108d9d44cfd8") - endomorphismB2 = fromHex("3086d221a7d46bcde86c90e49284eb15") +// hexToModNScalar converts the passed hex string into a ModNScalar and will +// panic if there is an error. This is only provided for the hard-coded +// constants so errors in the source code can be detected. It will only (and +// must only) be called with hard-coded values. +func hexToModNScalar(s string) *ModNScalar { + var isNegative bool + if len(s) > 0 && s[0] == '-' { + isNegative = true + s = s[1:] + } + if len(s)%2 != 0 { + s = "0" + s + } + b, err := hex.DecodeString(s) + if err != nil { + panic("invalid hex in source file: " + s) + } + var scalar ModNScalar + if overflow := scalar.SetByteSlice(b); overflow { + panic("hex in source file overflows mod N scalar: " + s) + } + if isNegative { + scalar.Negate() + } + return &scalar +} - // Alternatively, the following parameters are valid as well, however, they - // seem to be about 8% slower in practice. +var ( + // The following constants are used to accelerate scalar point + // multiplication through the use of the endomorphism: // - // endomorphismLambda = fromHex("AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE") - // endomorphismBeta = hexToFieldVal("851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40") - // endomorphismA1 = fromHex("E4437ED6010E88286F547FA90ABFE4C3") - // endomorphismB1 = fromHex("-3086D221A7D46BCDE86C90E49284EB15") - // endomorphismA2 = fromHex("3086D221A7D46BCDE86C90E49284EB15") - // endomorphismB2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8") + // φ(Q) ⟼ λ*Q = (β*Q.x mod p, Q.y) + // + // See the code in the deriveEndomorphismParams function in genprecomps.go + // for details on their derivation. + // + // Additionally, see the scalar multiplication function in this file for + // details on how they are used. + endoNegLambda = hexToModNScalar("-5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72") + endoBeta = hexToFieldVal("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee") + endoNegB1 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c3") + endoNegB2 = hexToModNScalar("-3086d221a7d46bcde86c90e49284eb15") + endoZ1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f") + endoZ2 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c4221208ac9df506c6") + + // Alternatively, the following parameters are valid as well, however, + // benchmarks show them to be about 2% slower in practice. + // endoNegLambda = hexToModNScalar("-ac9c52b33fa3cf1f5ad9e3fd77ed9ba4a880b9fc8ec739c2e0cfc810b51283ce") + // endoBeta = hexToFieldVal("851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40") + // endoNegB1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb15") + // endoNegB2 = hexToModNScalar("-114ca50f7a8e2f3f657c1108d9d44cfd8") + // endoZ1 = hexToModNScalar("114ca50f7a8e2f3f657c1108d9d44cfd95fbc92c10fddd145") + // endoZ2 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f") ) // JacobianPoint is an element of the group formed by the secp256k1 curve in @@ -178,7 +211,7 @@ func addZ1AndZ2EqualsOne(p1, p2, result *JacobianPoint) { y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4) z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6) - // Normalize the resulting field values to a magnitude of 1 as needed. + // Normalize the resulting field values as needed. x3.Normalize() y3.Normalize() z3.Normalize() @@ -196,7 +229,7 @@ func addZ1EqualsZ2(p1, p2, result *JacobianPoint) { // the equation into intermediate elements which are used to minimize // the number of field multiplications using a slightly modified version // of the method shown at: - // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl + // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-zadd-2007-m // // In particular it performs the calculations using the following: // A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B @@ -242,13 +275,13 @@ func addZ1EqualsZ2(p1, p2, result *JacobianPoint) { e.Mul2(x1, &b) // E = X1*B (mag: 1) negE.Set(&e).Negate(1) // negE = -E (mag: 2) f.Mul2(x2, &b) // F = X2*B (mag: 1) - x3.Add2(&e, &f).Negate(3).Add(&d) // X3 = D-E-F (mag: 5) - negX3.Set(x3).Negate(5).Normalize() // negX3 = -X3 (mag: 1) - y3.Set(y1).Mul(f.Add(&negE)).Negate(3) // Y3 = -(Y1*(F-E)) (mag: 4) - y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 5) + x3.Add2(&e, &f).Negate(2).Add(&d) // X3 = D-E-F (mag: 4) + negX3.Set(x3).Negate(4) // negX3 = -X3 (mag: 5) + y3.Set(y1).Mul(f.Add(&negE)).Negate(1) // Y3 = -(Y1*(F-E)) (mag: 2) + y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 3) z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1) - // Normalize the resulting field values to a magnitude of 1 as needed. + // Normalize the resulting field values as needed. x3.Normalize() y3.Normalize() z3.Normalize() @@ -330,7 +363,7 @@ func addZ2EqualsOne(p1, p2, result *JacobianPoint) { z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1) z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4) - // Normalize the resulting field values to a magnitude of 1 as needed. + // Normalize the resulting field values as needed. x3.Normalize() y3.Normalize() z3.Normalize() @@ -397,7 +430,7 @@ func addGeneric(p1, p2, result *JacobianPoint) { var negU1, negS1, negX3 FieldVal negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2) h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3) - i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 2) + i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 1) j.Mul2(&h, &i) // J = H*I (mag: 1) negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2) r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6) @@ -412,7 +445,7 @@ func addGeneric(p1, p2, result *JacobianPoint) { z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4) z3.Mul(&h) // Z3 = Z3*H (mag: 1) - // Normalize the resulting field values to a magnitude of 1 as needed. + // Normalize the resulting field values as needed. x3.Normalize() y3.Normalize() z3.Normalize() @@ -424,7 +457,7 @@ func addGeneric(p1, p2, result *JacobianPoint) { // NOTE: The points must be normalized for this function to return the correct // result. The resulting point will be normalized. func AddNonConst(p1, p2, result *JacobianPoint) { - // A point at infinity is the identity according to the group law for + // The point at infinity is the identity according to the group law for // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. if (p1.X.IsZero() && p1.Y.IsZero()) || p1.Z.IsZero() { result.Set(p2) @@ -508,7 +541,7 @@ func doubleZ1EqualsOne(p, result *JacobianPoint) { y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) - // Normalize the field values back to a magnitude of 1. + // Normalize the resulting field values as needed. x3.Normalize() y3.Normalize() z3.Normalize() @@ -562,7 +595,7 @@ func doubleGeneric(p, result *JacobianPoint) { y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9) y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10) - // Normalize the field values back to a magnitude of 1. + // Normalize the resulting field values as needed. x3.Normalize() y3.Normalize() z3.Normalize() @@ -574,7 +607,7 @@ func doubleGeneric(p, result *JacobianPoint) { // NOTE: The point must be normalized for this function to return the correct // result. The resulting point will be normalized. func DoubleNonConst(p, result *JacobianPoint) { - // Doubling a point at infinity is still infinity. + // Doubling the point at infinity is still infinity. if p.Y.IsZero() || p.Z.IsZero() { result.X.SetInt(0) result.Y.SetInt(0) @@ -596,47 +629,283 @@ func DoubleNonConst(p, result *JacobianPoint) { doubleGeneric(p, result) } -// splitK returns a balanced length-two representation of k and their signs. -// This is algorithm 3.74 from [GECC]. -// -// One thing of note about this algorithm is that no matter what c1 and c2 are, -// the final equation of k = k1 + k2 * lambda (mod n) will hold. This is -// provable mathematically due to how a1/b1/a2/b2 are computed. -// -// c1 and c2 are chosen to minimize the max(k1,k2). -func splitK(k []byte) ([]byte, []byte, int, int) { - // All math here is done with big.Int, which is slow. - // At some point, it might be useful to write something similar to - // FieldVal but for N instead of P as the prime field if this ends up - // being a bottleneck. - bigIntK := new(big.Int) - c1, c2 := new(big.Int), new(big.Int) - tmp1, tmp2 := new(big.Int), new(big.Int) - k1, k2 := new(big.Int), new(big.Int) +// mulAdd64 multiplies the two passed base 2^64 digits together, adds the given +// value to the result, and returns the 128-bit result via a (hi, lo) tuple +// where the upper half of the bits are returned in hi and the lower half in lo. +func mulAdd64(digit1, digit2, m uint64) (hi, lo uint64) { + // Note the carry on the final add is safe to discard because the maximum + // possible value is: + // (2^64 - 1)(2^64 - 1) + (2^64 - 1) = 2^128 - 2^64 + // and: + // 2^128 - 2^64 < 2^128. + var c uint64 + hi, lo = bits.Mul64(digit1, digit2) + lo, c = bits.Add64(lo, m, 0) + hi, _ = bits.Add64(hi, 0, c) + return hi, lo +} - bigIntK.SetBytes(k) - // c1 = round(b2 * k / n) from step 4. - // Rounding isn't really necessary and costs too much, hence skipped - c1.Mul(endomorphismB2, bigIntK) - c1.Div(c1, curveParams.N) - // c2 = round(b1 * k / n) from step 4 (sign reversed to optimize one step) - // Rounding isn't really necessary and costs too much, hence skipped - c2.Mul(endomorphismB1, bigIntK) - c2.Div(c2, curveParams.N) - // k1 = k - c1 * a1 - c2 * a2 from step 5 (note c2's sign is reversed) - tmp1.Mul(c1, endomorphismA1) - tmp2.Mul(c2, endomorphismA2) - k1.Sub(bigIntK, tmp1) - k1.Add(k1, tmp2) - // k2 = - c1 * b1 - c2 * b2 from step 5 (note c2's sign is reversed) - tmp1.Mul(c1, endomorphismB1) - tmp2.Mul(c2, endomorphismB2) - k2.Sub(tmp2, tmp1) +// mulAdd64Carry multiplies the two passed base 2^64 digits together, adds both +// the given value and carry to the result, and returns the 128-bit result via a +// (hi, lo) tuple where the upper half of the bits are returned in hi and the +// lower half in lo. +func mulAdd64Carry(digit1, digit2, m, c uint64) (hi, lo uint64) { + // Note the carry on the high order add is safe to discard because the + // maximum possible value is: + // (2^64 - 1)(2^64 - 1) + 2*(2^64 - 1) = 2^128 - 1 + // and: + // 2^128 - 1 < 2^128. + var c2 uint64 + hi, lo = mulAdd64(digit1, digit2, m) + lo, c2 = bits.Add64(lo, c, 0) + hi, _ = bits.Add64(hi, 0, c2) + return hi, lo +} - // Note Bytes() throws out the sign of k1 and k2. This matters - // since k1 and/or k2 can be negative. Hence, we pass that - // back separately. - return k1.Bytes(), k2.Bytes(), k1.Sign(), k2.Sign() +// mul512Rsh320Round computes the full 512-bit product of the two given scalars, +// right shifts the result by 320 bits, rounds to the nearest integer, and +// returns the result in constant time. +// +// Note that despite the inputs and output being mod n scalars, the 512-bit +// product is NOT reduced mod N prior to the right shift. This is intentional +// because it is used for replacing division with multiplication and thus the +// intermediate results must be done via a field extension to a larger field. +func mul512Rsh320Round(n1, n2 *ModNScalar) ModNScalar { + // Convert n1 and n2 to base 2^64 digits. + n1Digit0 := uint64(n1.n[0]) | uint64(n1.n[1])<<32 + n1Digit1 := uint64(n1.n[2]) | uint64(n1.n[3])<<32 + n1Digit2 := uint64(n1.n[4]) | uint64(n1.n[5])<<32 + n1Digit3 := uint64(n1.n[6]) | uint64(n1.n[7])<<32 + n2Digit0 := uint64(n2.n[0]) | uint64(n2.n[1])<<32 + n2Digit1 := uint64(n2.n[2]) | uint64(n2.n[3])<<32 + n2Digit2 := uint64(n2.n[4]) | uint64(n2.n[5])<<32 + n2Digit3 := uint64(n2.n[6]) | uint64(n2.n[7])<<32 + + // Compute the full 512-bit product n1*n2. + var r0, r1, r2, r3, r4, r5, r6, r7, c uint64 + + // Terms resulting from the product of the first digit of the second number + // by all digits of the first number. + // + // Note that r0 is ignored because it is not needed to compute the higher + // terms and it is shifted out below anyway. + c, _ = bits.Mul64(n2Digit0, n1Digit0) + c, r1 = mulAdd64(n2Digit0, n1Digit1, c) + c, r2 = mulAdd64(n2Digit0, n1Digit2, c) + r4, r3 = mulAdd64(n2Digit0, n1Digit3, c) + + // Terms resulting from the product of the second digit of the second number + // by all digits of the first number. + // + // Note that r1 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit1, n1Digit0, r1) + c, r2 = mulAdd64Carry(n2Digit1, n1Digit1, r2, c) + c, r3 = mulAdd64Carry(n2Digit1, n1Digit2, r3, c) + r5, r4 = mulAdd64Carry(n2Digit1, n1Digit3, r4, c) + + // Terms resulting from the product of the third digit of the second number + // by all digits of the first number. + // + // Note that r2 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit2, n1Digit0, r2) + c, r3 = mulAdd64Carry(n2Digit2, n1Digit1, r3, c) + c, r4 = mulAdd64Carry(n2Digit2, n1Digit2, r4, c) + r6, r5 = mulAdd64Carry(n2Digit2, n1Digit3, r5, c) + + // Terms resulting from the product of the fourth digit of the second number + // by all digits of the first number. + // + // Note that r3 is ignored because it is no longer needed to compute the + // higher terms and it is shifted out below anyway. + c, _ = mulAdd64(n2Digit3, n1Digit0, r3) + c, r4 = mulAdd64Carry(n2Digit3, n1Digit1, r4, c) + c, r5 = mulAdd64Carry(n2Digit3, n1Digit2, r5, c) + r7, r6 = mulAdd64Carry(n2Digit3, n1Digit3, r6, c) + + // At this point the upper 256 bits of the full 512-bit product n1*n2 are in + // r4..r7 (recall the low order results were discarded as noted above). + // + // Right shift the result 320 bits. Note that the MSB of r4 determines + // whether or not to round because it is the final bit that is shifted out. + // + // Also, notice that r3..r7 would also ordinarily be set to 0 as well for + // the full shift, but that is skipped since they are no longer used as + // their values are known to be zero. + roundBit := r4 >> 63 + r2, r1, r0 = r7, r6, r5 + + // Conditionally add 1 depending on the round bit in constant time. + r0, c = bits.Add64(r0, roundBit, 0) + r1, c = bits.Add64(r1, 0, c) + r2, r3 = bits.Add64(r2, 0, c) + + // Finally, convert the result to a mod n scalar. + // + // No modular reduction is needed because the result is guaranteed to be + // less than the group order given the group order is > 2^255 and the + // maximum possible value of the result is 2^192. + var result ModNScalar + result.n[0] = uint32(r0) + result.n[1] = uint32(r0 >> 32) + result.n[2] = uint32(r1) + result.n[3] = uint32(r1 >> 32) + result.n[4] = uint32(r2) + result.n[5] = uint32(r2 >> 32) + result.n[6] = uint32(r3) + result.n[7] = uint32(r3 >> 32) + return result +} + +// splitK returns two scalars (k1 and k2) that are a balanced length-two +// representation of the provided scalar such that k ≡ k1 + k2*λ (mod N), where +// N is the secp256k1 group order. +func splitK(k *ModNScalar) (ModNScalar, ModNScalar) { + // The ultimate goal is to decompose k into two scalars that are around + // half the bit length of k such that the following equation is satisfied: + // + // k1 + k2*λ ≡ k (mod n) + // + // The strategy used here is based on algorithm 3.74 from [GECC] with a few + // modifications to make use of the more efficient mod n scalar type, avoid + // some costly long divisions, and minimize the number of calculations. + // + // Start by defining a function that takes a vector v = ∈ ℤ⨯ℤ: + // + // f(v) = a + bλ (mod n) + // + // Then, find two vectors, v1 = , and v2 = in ℤ⨯ℤ such that: + // 1) v1 and v2 are linearly independent + // 2) f(v1) = f(v2) = 0 + // 3) v1 and v2 have small Euclidean norm + // + // The vectors that satisfy these properties are found via the Euclidean + // algorithm and are precomputed since both n and λ are fixed values for the + // secp256k1 curve. See genprecomps.go for derivation details. + // + // Next, consider k as a vector in ℚ⨯ℚ and by linear algebra write: + // + // = g1*v1 + g2*v2, where g1, g2 ∈ ℚ + // + // Note that, per above, the components of vector v1 are a1 and b1 while the + // components of vector v2 are a2 and b2. Given the vectors v1 and v2 were + // generated such that a1*b2 - a2*b1 = n, solving the equation for g1 and g2 + // yields: + // + // g1 = b2*k / n + // g2 = -b1*k / n + // + // Observe: + // = g1*v1 + g2*v2 + // = (b2*k/n)* + (-b1*k/n)* | substitute + // = + <-a2*b1*k/n, -b2*b1*k/n> | scalar mul + // = | vector add + // = <[a1*b2*k - a2*b1*k]/n, 0> | simplify + // = | factor out k + // = | substitute + // = | simplify + // + // Now, consider an integer-valued vector v: + // + // v = c1*v1 + c2*v2, where c1, c2 ∈ ℤ (mod n) + // + // Since vectors v1 and v2 are linearly independent and were generated such + // that f(v1) = f(v2) = 0, all possible scalars c1 and c2 also produce a + // vector v such that f(v) = 0. + // + // In other words, c1 and c2 can be any integers and the resulting + // decomposition will still satisfy the required equation. However, since + // the goal is to produce a balanced decomposition that provides a + // performance advantage by minimizing max(k1, k2), c1 and c2 need to be + // integers close to g1 and g2, respectively, so the resulting vector v is + // an integer-valued vector that is close to . + // + // Finally, consider the vector u: + // + // u = - v + // + // It follows that f(u) = k and thus the two components of vector u satisfy + // the required equation: + // + // k1 + k2*λ ≡ k (mod n) + // + // Choosing c1 and c2: + // ------------------- + // + // As mentioned above, c1 and c2 need to be integers close to g1 and g2, + // respectively. The algorithm in [GECC] chooses the following values: + // + // c1 = round(g1) = round(b2*k / n) + // c2 = round(g2) = round(-b1*k / n) + // + // However, as section 3.4.2 of [STWS] notes, the aforementioned approach + // requires costly long divisions that can be avoided by precomputing + // rounded estimates as follows: + // + // t = bitlen(n) + 1 + // z1 = round(2^t * b2 / n) + // z2 = round(2^t * -b1 / n) + // + // Then, use those precomputed estimates to perform a multiplication by k + // along with a floored division by 2^t, which is a simple right shift by t: + // + // c1 = floor(k * z1 / 2^t) = (k * z1) >> t + // c2 = floor(k * z2 / 2^t) = (k * z2) >> t + // + // Finally, round up if last bit discarded in the right shift by t is set by + // adding 1. + // + // As a further optimization, rather than setting t = bitlen(n) + 1 = 257 as + // stated by [STWS], this implementation uses a higher precision estimate of + // t = bitlen(n) + 64 = 320 because it allows simplification of the shifts + // in the internal calculations that are done via uint64s and also allows + // the use of floor in the precomputations. + // + // Thus, the calculations this implementation uses are: + // + // z1 = floor(b2<<320 / n) | precomputed + // z2 = floor((-b1)<<320) / n) | precomputed + // c1 = ((k * z1) >> 320) + (((k * z1) >> 319) & 1) + // c2 = ((k * z2) >> 320) + (((k * z2) >> 319) & 1) + // + // Putting it all together: + // ------------------------ + // + // Calculate the following vectors using the values discussed above: + // + // v = c1*v1 + c2*v2 + // u = - v + // + // The two components of the resulting vector v are: + // va = c1*a1 + c2*a2 + // vb = c1*b1 + c2*b2 + // + // Thus, the two components of the resulting vector u are: + // k1 = k - va + // k2 = 0 - vb = -vb + // + // As some final optimizations: + // + // 1) Note that k1 + k2*λ ≡ k (mod n) means that k1 ≡ k - k2*λ (mod n). + // Therefore, the computation of va can be avoided to save two + // field multiplications and a field addition. + // + // 2) Since k1 = k - k2*λ = k + k2*(-λ), an additional field negation is + // saved by storing and using the negative version of λ. + // + // 3) Since k2 = -vb = -(c1*b1 + c2*b2) = c1*(-b1) + c2*(-b2), one more + // field negation is saved by storing and using the negative versions of + // b1 and b2. + // + // k2 = c1*(-b1) + c2*(-b2) + // k1 = k + k2*(-λ) + var k1, k2 ModNScalar + c1 := mul512Rsh320Round(k, endoZ1) + c2 := mul512Rsh320Round(k, endoZ2) + k2.Add2(c1.Mul(endoNegB1), c2.Mul(endoNegB2)) + k1.Mul2(&k2, endoNegLambda).Add(k) + return k1, k2 } // nafScalar represents a positive integer up to a maximum value of 2^256 - 1 @@ -775,70 +1044,132 @@ func naf(k []byte) nafScalar { return result } -// ScalarMultNonConst multiplies k*P where k is a big endian integer modulo the -// curve order and P is a point in Jacobian projective coordinates and stores -// the result in the provided Jacobian point. +// ScalarMultNonConst multiplies k*P where k is a scalar modulo the curve order +// and P is a point in Jacobian projective coordinates and stores the result in +// the provided Jacobian point. // // NOTE: The point must be normalized for this function to return the correct // result. The resulting point will be normalized. func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { - // Decompose K into k1 and k2 in order to halve the number of EC ops. - // See Algorithm 3.74 in [GECC]. - kBytes := k.Bytes() - k1, k2, signK1, signK2 := splitK(kBytes[:]) - zeroArray32(&kBytes) - - // The main equation here to remember is: - // k * P = k1 * P + k2 * ϕ(P) + // ------------------------------------------------------------------------- + // This makes use of the following efficiently-computable endomorphism to + // accelerate the computation: // - // P1 below is P in the equation, P2 below is ϕ(P) in the equation + // φ(P) ⟼ λ*P = (β*P.x mod p, P.y) + // + // In other words, there is a special scalar λ that every point on the + // elliptic curve can be multiplied by that will result in the same point as + // performing a single field multiplication of the point's X coordinate by + // the special value β. + // + // This is useful because scalar point multiplication is significantly more + // expensive than a single field multiplication given the former involves a + // series of point doublings and additions which themselves consist of a + // combination of several field multiplications, squarings, and additions. + // + // So, the idea behind making use of the endomorphism is thus to decompose + // the scalar into two scalars that are each about half the bit length of + // the original scalar such that: + // + // k ≡ k1 + k2*λ (mod n) + // + // This in turn allows the scalar point multiplication to be performed as a + // sum of two smaller half-length multiplications as follows: + // + // k*P = (k1 + k2*λ)*P + // = k1*P + k2*λ*P + // = k1*P + k2*φ(P) + // + // Thus, a speedup is achieved so long as it's faster to decompose the + // scalar, compute φ(P), and perform a simultaneous multiply of the + // half-length point multiplications than it is to compute a full width + // point multiplication. + // + // In practice, benchmarks show the current implementation provides a + // speedup of around 30-35% versus not using the endomorphism. + // + // See section 3.5 in [GECC] for a more rigorous treatment. + // ------------------------------------------------------------------------- + + // Per above, the main equation here to remember is: + // k*P = k1*P + k2*φ(P) + // + // p1 below is P in the equation while p2 is φ(P) in the equation. + // + // NOTE: φ(x,y) = (β*x,y). The Jacobian z coordinates are the same, so this + // math goes through. + // + // Also, calculate -p1 and -p2 for use in the NAF optimization. p1, p1Neg := new(JacobianPoint), new(JacobianPoint) p1.Set(point) p1Neg.Set(p1) p1Neg.Y.Negate(1).Normalize() - - // NOTE: ϕ(x,y) = (βx,y). The Jacobian z coordinates are the same, so this - // math goes through. p2, p2Neg := new(JacobianPoint), new(JacobianPoint) p2.Set(p1) - p2.X.Mul(endomorphismBeta).Normalize() + p2.X.Mul(endoBeta).Normalize() p2Neg.Set(p2) p2Neg.Y.Negate(1).Normalize() - // Flip the positive and negative values of the points as needed - // depending on the signs of k1 and k2. As mentioned in the equation - // above, each of k1 and k2 are multiplied by the respective point. - // Since -k * P is the same thing as k * -P, and the group law for - // elliptic curves states that P(x, y) = -P(x, -y), it's faster and - // simplifies the code to just make the point negative. - if signK1 == -1 { + // Decompose k into k1 and k2 such that k = k1 + k2*λ (mod n) where k1 and + // k2 are around half the bit length of k in order to halve the number of EC + // operations. + // + // Notice that this also flips the sign of the scalars and points as needed + // to minimize the bit lengths of the scalars k1 and k2. + // + // This is done because the scalars are operating modulo the group order + // which means that when they would otherwise be a small negative magnitude + // they will instead be a large positive magnitude. Since the goal is for + // the scalars to have a small magnitude to achieve a performance boost, use + // their negation when they are greater than the half order of the group and + // flip the positive and negative values of the corresponding point that + // will be multiplied by to compensate. + // + // In other words, transform the calc when k1 is over the half order to: + // k1*P = -k1*-P + // + // Similarly, transform the calc when k2 is over the half order to: + // k2*φ(P) = -k2*-φ(P) + k1, k2 := splitK(k) + if k1.IsOverHalfOrder() { + k1.Negate() p1, p1Neg = p1Neg, p1 } - if signK2 == -1 { + if k2.IsOverHalfOrder() { + k2.Negate() p2, p2Neg = p2Neg, p2 } - // NAF versions of k1 and k2 should have a lot more zeros. + // Convert k1 and k2 into their NAF representations since NAF has a lot more + // zeros overall on average which minimizes the number of required point + // additions in exchange for a mix of fewer point additions and subtractions + // at the cost of one additional point doubling. // - // The Pos version of the bytes contain the +1s and the Neg versions - // contain the -1s. - k1NAF, k2NAF := naf(k1), naf(k2) + // This is an excellent tradeoff because subtraction of points has the same + // computational complexity as addition of points and point doubling is + // faster than both. + // + // Concretely, on average, 1/2 of all bits will be non-zero with the normal + // binary representation whereas only 1/3rd of the bits will be non-zero + // with NAF. + // + // The Pos version of the bytes contain the +1s and the Neg versions contain + // the -1s. + k1Bytes, k2Bytes := k1.Bytes(), k2.Bytes() + k1NAF, k2NAF := naf(k1Bytes[:]), naf(k2Bytes[:]) k1PosNAF, k1NegNAF := k1NAF.Pos(), k1NAF.Neg() k2PosNAF, k2NegNAF := k2NAF.Pos(), k2NAF.Neg() k1Len, k2Len := len(k1PosNAF), len(k2PosNAF) + // Add left-to-right using the NAF optimization. See algorithm 3.77 from + // [GECC]. + // + // Point Q = ∞ (point at infinity). + var q JacobianPoint m := k1Len if m < k2Len { m = k2Len } - - // Point Q = ∞ (point at infinity). - var q JacobianPoint - - // Add left-to-right using the NAF optimization. See algorithm 3.77 - // from [GECC]. This should be faster overall since there will be a lot - // more instances of 0, hence reducing the number of Jacobian additions - // at the cost of 1 possible extra doubling. for i := 0; i < m; i++ { // Since k1 and k2 are potentially different lengths and the calculation // is being done left to right, pad the front of the shorter one with @@ -850,7 +1181,8 @@ func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { if i >= m-k2Len { k2BytePos, k2ByteNeg = k2PosNAF[i-(m-k2Len)], k2NegNAF[i-(m-k2Len)] } - for bit, mask := 7, uint8(1<<7); bit >= 0; bit, mask = bit-1, mask>>1 { + + for mask := uint8(1 << 7); mask > 0; mask >>= 1 { // Q = 2 * Q DoubleNonConst(&q, &q) @@ -883,31 +1215,28 @@ func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { result.Set(&q) } -// ScalarBaseMultNonConst multiplies k*G where G is the base point of the group -// and k is a big endian integer. The result is stored in Jacobian coordinates -// (x1, y1, z1). +// ScalarBaseMultNonConst multiplies k*G where k is a scalar modulo the curve +// order and G is the base point of the group and stores the result in the +// provided Jacobian point. // // NOTE: The resulting point will be normalized. func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { bytePoints := s256BytePoints() - // Point Q = ∞ (point at infinity). - var q JacobianPoint + // Start with the point at infinity. + result.X.Zero() + result.Y.Zero() + result.Z.Zero() - // curve.bytePoints has all 256 byte points for each 8-bit window. The - // strategy is to add up the byte points. This is best understood by - // expressing k in base-256 which it already sort of is. Each "digit" in - // the 8-bit window can be looked up using bytePoints and added together. - var pt JacobianPoint - for i, byteVal := range k.Bytes() { - p := bytePoints[i][byteVal] - pt.X.Set(&p[0]) - pt.Y.Set(&p[1]) - pt.Z.SetInt(1) - AddNonConst(&q, &pt, &q) + // bytePoints has all 256 byte points for each 8-bit window. The strategy + // is to add up the byte points. This is best understood by expressing k in + // base-256 which it already sort of is. Each "digit" in the 8-bit window + // can be looked up using bytePoints and added together. + kb := k.Bytes() + for i := 0; i < len(kb); i++ { + pt := &bytePoints[i][kb[i]] + AddNonConst(result, pt, result) } - - result.Set(&q) } // isOnCurve returns whether or not the affine point (x,y) is on the curve. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go index 91a670e51..ac01e2343 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go @@ -1,10 +1,11 @@ // Copyright (c) 2013-2014 The btcsuite developers -// Copyright (c) 2015-2019 The Decred developers +// Copyright (c) 2015-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. /* -Package secp256k1 implements optimized secp256k1 elliptic curve operations. +Package secp256k1 implements optimized secp256k1 elliptic curve operations in +pure Go. This package provides an optimized pure Go implementation of elliptic curve cryptography operations over the secp256k1 curve as well as data structures and @@ -18,22 +19,22 @@ packages for more details about those aspects. An overview of the features provided by this package are as follows: - - Private key generation, serialization, and parsing - - Public key generation, serialization and parsing per ANSI X9.62-1998 - - Parses uncompressed, compressed, and hybrid public keys - - Serializes uncompressed and compressed public keys - - Specialized types for performing optimized and constant time field operations - - FieldVal type for working modulo the secp256k1 field prime - - ModNScalar type for working modulo the secp256k1 group order - - Elliptic curve operations in Jacobian projective coordinates - - Point addition - - Point doubling - - Scalar multiplication with an arbitrary point - - Scalar multiplication with the base point (group generator) - - Point decompression from a given x coordinate - - Nonce generation via RFC6979 with support for extra data and version - information that can be used to prevent nonce reuse between signing - algorithms + - Private key generation, serialization, and parsing + - Public key generation, serialization and parsing per ANSI X9.62-1998 + - Parses uncompressed, compressed, and hybrid public keys + - Serializes uncompressed and compressed public keys + - Specialized types for performing optimized and constant time field operations + - FieldVal type for working modulo the secp256k1 field prime + - ModNScalar type for working modulo the secp256k1 group order + - Elliptic curve operations in Jacobian projective coordinates + - Point addition + - Point doubling + - Scalar multiplication with an arbitrary point + - Scalar multiplication with the base point (group generator) + - Point decompression from a given x coordinate + - Nonce generation via RFC6979 with support for extra data and version + information that can be used to prevent nonce reuse between signing + algorithms It also provides an implementation of the Go standard library crypto/elliptic Curve interface via the S256 function so that it may be used with other packages @@ -49,7 +50,7 @@ use optimized secp256k1 elliptic curve cryptography. Finally, a comprehensive suite of tests is provided to provide a high level of quality assurance. -Use of secp256k1 in Decred +# Use of secp256k1 in Decred At the time of this writing, the primary public key cryptography in widespread use on the Decred network used to secure coins is based on elliptic curves diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/doc.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/doc.go index 14f38ef30..6a1c070ac 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/doc.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/doc.go @@ -21,7 +21,7 @@ hash combination. A comprehensive suite of tests is provided to ensure proper functionality. -ECDSA use in Decred +# ECDSA use in Decred At the time of this writing, ECDSA signatures are heavily used for proving coin ownership in Decred as the vast majority of transactions consist of what is @@ -30,7 +30,7 @@ private key only known to the recipient of the coins along with an encumbrance that requires an ECDSA signature that proves the new owner possesses the private key without actually revealing it. -Errors +# Errors Errors returned by this package are of type ecdsa.Error and fully support the standard library errors.Is and errors.As functions. This allows the caller to diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/error.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/error.go index 45f82525b..6136ece37 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/error.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/error.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 The Decred developers +// Copyright (c) 2020-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -85,6 +85,24 @@ const ( // ErrSigSTooBig is returned when a signature has S with a value that is // greater than or equal to the group order. ErrSigSTooBig = ErrorKind("ErrSigSTooBig") + + // ErrSigInvalidLen is returned when a signature that should be a compact + // signature is not the required length. + ErrSigInvalidLen = ErrorKind("ErrSigInvalidLen") + + // ErrSigInvalidRecoveryCode is returned when a signature that should be a + // compact signature has an invalid value for the public key recovery code. + ErrSigInvalidRecoveryCode = ErrorKind("ErrSigInvalidRecoveryCode") + + // ErrSigOverflowsPrime is returned when a signature that should be a + // compact signature has the overflow bit set but adding the order to it + // would overflow the underlying field prime. + ErrSigOverflowsPrime = ErrorKind("ErrSigOverflowsPrime") + + // ErrPointNotOnCurve is returned when attempting to recover a public key + // from a compact signature results in a point that is not on the elliptic + // curve. + ErrPointNotOnCurve = ErrorKind("ErrPointNotOnCurve") ) // Error satisfies the error interface and prints human-readable errors. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/signature.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/signature.go index 50f1721a9..cfa7a4877 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/signature.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/signature.go @@ -1,12 +1,11 @@ // Copyright (c) 2013-2014 The btcsuite developers -// Copyright (c) 2015-2020 The Decred developers +// Copyright (c) 2015-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package ecdsa import ( - "errors" "fmt" "github.com/decred/dcrd/dcrec/secp256k1/v4" @@ -30,10 +29,10 @@ var ( // orderAsFieldVal is the order of the secp256k1 curve group stored as a // field value. It is provided here to avoid the need to create it multiple // times. - orderAsFieldVal = func() *secp256k1.FieldVal { + orderAsFieldVal = func() secp256k1.FieldVal { var f secp256k1.FieldVal f.SetByteSlice(secp256k1.Params().N.Bytes()) - return &f + return f }() ) @@ -283,7 +282,7 @@ func (sig *Signature) Verify(hash []byte, pubKey *secp256k1.PublicKey) bool { // Step 10. // // Verified if (R + N) * z == X.x (mod P) - sigRModP.Add(orderAsFieldVal) + sigRModP.Add(&orderAsFieldVal) result.Mul2(&sigRModP, z).Normalize() return result.Equals(&X.X) } @@ -535,8 +534,130 @@ func ParseDERSignature(sig []byte) (*Signature, error) { return NewSignature(&r, &s), nil } +// sign generates an ECDSA signature over the secp256k1 curve for the provided +// hash (which should be the result of hashing a larger message) using the given +// nonce and private key and returns it along with an additional public key +// recovery code and success indicator. Upon success, the produced signature is +// deterministic (same message, nonce, and key yield the same signature) and +// canonical in accordance with BIP0062. +// +// Note that signRFC6979 makes use of this function as it is the primary ECDSA +// signing logic. It differs in that it accepts a nonce to use when signing and +// may not successfully produce a valid signature for the given nonce. It is +// primarily separated for testing purposes. +func sign(privKey, nonce *secp256k1.ModNScalar, hash []byte) (*Signature, byte, bool) { + // The algorithm for producing an ECDSA signature is given as algorithm 4.29 + // in [GECC]. + // + // The following is a paraphrased version for reference: + // + // G = curve generator + // N = curve order + // d = private key + // m = message + // r, s = signature + // + // 1. Select random nonce k in [1, N-1] + // 2. Compute kG + // 3. r = kG.x mod N (kG.x is the x coordinate of the point kG) + // Repeat from step 1 if r = 0 + // 4. e = H(m) + // 5. s = k^-1(e + dr) mod N + // Repeat from step 1 if s = 0 + // 6. Return (r,s) + // + // This is slightly modified here to conform to RFC6979 and BIP 62 as + // follows: + // + // A. Instead of selecting a random nonce in step 1, use RFC6979 to generate + // a deterministic nonce in [1, N-1] parameterized by the private key, + // message being signed, and an iteration count for the repeat cases + // B. Negate s calculated in step 5 if it is > N/2 + // This is done because both s and its negation are valid signatures + // modulo the curve order N, so it forces a consistent choice to reduce + // signature malleability + + // NOTE: Step 1 is performed by the caller. + // + // Step 2. + // + // Compute kG + // + // Note that the point must be in affine coordinates. + k := nonce + var kG secp256k1.JacobianPoint + secp256k1.ScalarBaseMultNonConst(k, &kG) + kG.ToAffine() + + // Step 3. + // + // r = kG.x mod N + // Repeat from step 1 if r = 0 + r, overflow := fieldToModNScalar(&kG.X) + if r.IsZero() { + return nil, 0, false + } + + // Since the secp256k1 curve has a cofactor of 1, when recovering a + // public key from an ECDSA signature over it, there are four possible + // candidates corresponding to the following cases: + // + // 1) The X coord of the random point is < N and its Y coord even + // 2) The X coord of the random point is < N and its Y coord is odd + // 3) The X coord of the random point is >= N and its Y coord is even + // 4) The X coord of the random point is >= N and its Y coord is odd + // + // Rather than forcing the recovery procedure to check all possible + // cases, this creates a recovery code that uniquely identifies which of + // the cases apply by making use of 2 bits. Bit 0 identifies the + // oddness case and Bit 1 identifies the overflow case (aka when the X + // coord >= N). + // + // It is also worth noting that making use of Hasse's theorem shows + // there are around log_2((p-n)/p) ~= -127.65 ~= 1 in 2^127 points where + // the X coordinate is >= N. It is not possible to calculate these + // points since that would require breaking the ECDLP, but, in practice + // this strongly implies with extremely high probability that there are + // only a few actual points for which this case is true. + pubKeyRecoveryCode := byte(overflow<<1) | byte(kG.Y.IsOddBit()) + + // Step 4. + // + // e = H(m) + // + // Note that this actually sets e = H(m) mod N which is correct since + // it is only used in step 5 which itself is mod N. + var e secp256k1.ModNScalar + e.SetByteSlice(hash) + + // Step 5 with modification B. + // + // s = k^-1(e + dr) mod N + // Repeat from step 1 if s = 0 + // s = -s if s > N/2 + kinv := new(secp256k1.ModNScalar).InverseValNonConst(k) + s := new(secp256k1.ModNScalar).Mul2(privKey, &r).Add(&e).Mul(kinv) + if s.IsZero() { + return nil, 0, false + } + if s.IsOverHalfOrder() { + s.Negate() + + // Negating s corresponds to the random point that would have been + // generated by -k (mod N), which necessarily has the opposite + // oddness since N is prime, thus flip the pubkey recovery code + // oddness bit accordingly. + pubKeyRecoveryCode ^= 0x01 + } + + // Step 6. + // + // Return (r,s) + return NewSignature(&r, s), pubKeyRecoveryCode, true +} + // signRFC6979 generates a deterministic ECDSA signature according to RFC 6979 -// and BIP 62 and returns it along with an additional public key recovery code +// and BIP0062 and returns it along with an additional public key recovery code // for efficiently recovering the public key from the signature. func signRFC6979(privKey *secp256k1.PrivateKey, hash []byte) (*Signature, byte) { // The algorithm for producing an ECDSA signature is given as algorithm 4.29 @@ -581,82 +702,14 @@ func signRFC6979(privKey *secp256k1.PrivateKey, hash []byte) (*Signature, byte) // private key, message being signed, and iteration count. k := secp256k1.NonceRFC6979(privKeyBytes[:], hash, nil, nil, iteration) - // Step 2. - // - // Compute kG - // - // Note that the point must be in affine coordinates. - var kG secp256k1.JacobianPoint - secp256k1.ScalarBaseMultNonConst(k, &kG) - kG.ToAffine() - - // Step 3. - // - // r = kG.x mod N - // Repeat from step 1 if r = 0 - r, overflow := fieldToModNScalar(&kG.X) - if r.IsZero() { - k.Zero() - continue - } - - // Since the secp256k1 curve has a cofactor of 1, when recovering a - // public key from an ECDSA signature over it, there are four possible - // candidates corresponding to the following cases: - // - // 1) The X coord of the random point is < N and its Y coord even - // 2) The X coord of the random point is < N and its Y coord is odd - // 3) The X coord of the random point is >= N and its Y coord is even - // 4) The X coord of the random point is >= N and its Y coord is odd - // - // Rather than forcing the recovery procedure to check all possible - // cases, this creates a recovery code that uniquely identifies which of - // the cases apply by making use of 2 bits. Bit 0 identifies the - // oddness case and Bit 1 identifies the overflow case (aka when the X - // coord >= N). - // - // It is also worth noting that making use of Hasse's theorem shows - // there are around log_2((p-n)/p) ~= -127.65 ~= 1 in 2^127 points where - // the X coordinate is >= N. It is not possible to calculate these - // points since that would require breaking the ECDLP, but, in practice - // this strongly implies with extremely high probability that there are - // only a few actual points for which this case is true. - pubKeyRecoveryCode := byte(overflow<<1) | byte(kG.Y.IsOddBit()) - - // Step 4. - // - // e = H(m) - // - // Note that this actually sets e = H(m) mod N which is correct since - // it is only used in step 5 which itself is mod N. - var e secp256k1.ModNScalar - e.SetByteSlice(hash) - - // Step 5 with modification B. - // - // s = k^-1(e + dr) mod N - // Repeat from step 1 if s = 0 - // s = -s if s > N/2 - kInv := new(secp256k1.ModNScalar).InverseValNonConst(k) + // Steps 2-6. + sig, pubKeyRecoveryCode, success := sign(privKeyScalar, k, hash) k.Zero() - s := new(secp256k1.ModNScalar).Mul2(privKeyScalar, &r).Add(&e).Mul(kInv) - if s.IsZero() { + if !success { continue } - if s.IsOverHalfOrder() { - s.Negate() - // Negating s corresponds to the random point that would have been - // generated by -k (mod N), which necessarily has the opposite - // oddness since N is prime, thus flip the pubkey recovery code - // oddness bit accordingly. - pubKeyRecoveryCode ^= 0x01 - } - - // Step 6. - // - // Return (r,s) - return NewSignature(&r, s), pubKeyRecoveryCode + return sig, pubKeyRecoveryCode } } @@ -769,7 +822,7 @@ func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) // The method described by section 4.1.6 of [SEC1] to determine which one is // the correct one involves calculating each possibility as a candidate // public key and comparing the candidate to the authentic public key. It - // also hints that is is possible to generate the signature in a such a + // also hints that it is possible to generate the signature in a such a // way that only one of the candidate public keys is viable. // // A more efficient approach that is specific to the secp256k1 curve is used @@ -797,7 +850,9 @@ func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) // A compact signature consists of a recovery byte followed by the R and // S components serialized as 32-byte big-endian values. if len(signature) != compactSigSize { - return nil, false, errors.New("invalid compact signature size") + str := fmt.Sprintf("malformed signature: wrong size: %d != %d", + len(signature), compactSigSize) + return nil, false, signatureError(ErrSigInvalidLen, str) } // Parse and validate the compact signature recovery code. @@ -807,7 +862,10 @@ func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) ) sigRecoveryCode := signature[0] if sigRecoveryCode < minValidCode || sigRecoveryCode > maxValidCode { - return nil, false, errors.New("invalid compact signature recovery code") + str := fmt.Sprintf("invalid signature: public key recovery code %d is "+ + "not in the valid range [%d, %d]", sigRecoveryCode, minValidCode, + maxValidCode) + return nil, false, signatureError(ErrSigInvalidRecoveryCode, str) } sigRecoveryCode -= compactSigMagicOffset wasCompressed := sigRecoveryCode&compactSigCompPubKey != 0 @@ -820,16 +878,20 @@ func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) // Fail if r and s are not in [1, N-1]. var r, s secp256k1.ModNScalar if overflow := r.SetByteSlice(signature[1:33]); overflow { - return nil, false, errors.New("signature R is >= curve order") + str := "invalid signature: R >= group order" + return nil, false, signatureError(ErrSigRTooBig, str) } if r.IsZero() { - return nil, false, errors.New("signature R is 0") + str := "invalid signature: R is 0" + return nil, false, signatureError(ErrSigRIsZero, str) } if overflow := s.SetByteSlice(signature[33:]); overflow { - return nil, false, errors.New("signature S is >= curve order") + str := "invalid signature: S >= group order" + return nil, false, signatureError(ErrSigSTooBig, str) } if s.IsZero() { - return nil, false, errors.New("signature S is 0") + str := "invalid signature: S is 0" + return nil, false, signatureError(ErrSigSIsZero, str) } // Step 2. @@ -850,13 +912,14 @@ func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) // would exceed the field prime since R originally came from the X // coordinate of a random point on the curve. if fieldR.IsGtOrEqPrimeMinusOrder() { - return nil, false, errors.New("signature R + N >= P") + str := "invalid signature: signature R + N >= P" + return nil, false, signatureError(ErrSigOverflowsPrime, str) } // Step 3.2. // // r = r + N (mod P) - fieldR.Add(orderAsFieldVal) + fieldR.Add(&orderAsFieldVal) } // Step 4. @@ -871,15 +934,16 @@ func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) oddY := pubKeyRecoveryCode&pubKeyRecoveryCodeOddnessBit != 0 var y secp256k1.FieldVal if valid := secp256k1.DecompressY(&fieldR, oddY, &y); !valid { - return nil, false, errors.New("signature is not for a valid curve point") + str := "invalid signature: not for a valid curve point" + return nil, false, signatureError(ErrPointNotOnCurve, str) } // Step 5. // // X = (r, y) var X secp256k1.JacobianPoint - X.X.Set(&fieldR) - X.Y.Set(&y) + X.X.Set(fieldR.Normalize()) + X.Y.Set(y.Normalize()) X.Z.SetInt(1) // Step 6. @@ -915,7 +979,8 @@ func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) // Either the signature or the pubkey recovery code must be invalid if the // recovered pubkey is the point at infinity. if (Q.X.IsZero() && Q.Y.IsZero()) || Q.Z.IsZero() { - return nil, false, errors.New("recovered pubkey is the point at infinity") + str := "invalid signature: recovered pubkey is the point at infinity" + return nil, false, signatureError(ErrPointNotOnCurve, str) } // Notice that the public key is in affine coordinates. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go index a271ff6b3..42022646b 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go @@ -1,4 +1,4 @@ -// Copyright 2020-2021 The Decred developers +// Copyright 2020-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -102,7 +102,7 @@ func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool { // // This is part of the elliptic.Curve interface implementation. func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { - // A point at infinity is the identity according to the group law for + // The point at infinity is the identity according to the group law for // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P. if x1.Sign() == 0 && y1.Sign() == 0 { return x2, y2 @@ -249,7 +249,7 @@ var secp256k1 = &KoblitzCurve{ }, } -// S256 returns a Curve which implements secp256k1. +// S256 returns an elliptic.Curve which implements secp256k1. func S256() *KoblitzCurve { return secp256k1 } diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go index 43e27a91d..8d9ac74d5 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go @@ -1,6 +1,6 @@ // Copyright (c) 2013-2014 The btcsuite developers -// Copyright (c) 2015-2021 The Decred developers -// Copyright (c) 2013-2021 Dave Collins +// Copyright (c) 2015-2022 The Decred developers +// Copyright (c) 2013-2022 Dave Collins // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -103,7 +103,8 @@ const ( // FieldVal implements optimized fixed-precision arithmetic over the // secp256k1 finite field. This means all arithmetic is performed modulo -// 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f. +// +// 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f. // // WARNING: Since it is so important for the field arithmetic to be extremely // fast for high performance crypto, this type does not perform any validation @@ -172,9 +173,9 @@ type FieldVal struct { // String returns the field value as a normalized human-readable hex string. // -// Preconditions: None -// Output Normalized: Field is not modified -- same as input value -// Output Max Magnitude: Field is not modified -- same as input value +// Preconditions: None +// Output Normalized: Field is not modified -- same as input value +// Output Max Magnitude: Field is not modified -- same as input value func (f FieldVal) String() string { // f is a copy, so it's safe to normalize it without mutating the original. f.Normalize() @@ -185,9 +186,9 @@ func (f FieldVal) String() string { // value is already set to zero. This function can be useful to clear an // existing field value for reuse. // -// Preconditions: None -// Output Normalized: Yes -// Output Max Magnitude: 1 +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 func (f *FieldVal) Zero() { f.n[0] = 0 f.n[1] = 0 @@ -208,9 +209,9 @@ func (f *FieldVal) Zero() { // f := new(FieldVal).Set(f2).Add(1) so that f = f2 + 1 where f2 is not // modified. // -// Preconditions: None -// Output Normalized: Same as input value -// Output Max Magnitude: Same as input value +// Preconditions: None +// Output Normalized: Same as input value +// Output Max Magnitude: Same as input value func (f *FieldVal) Set(val *FieldVal) *FieldVal { *f = *val return f @@ -223,9 +224,9 @@ func (f *FieldVal) Set(val *FieldVal) *FieldVal { // The field value is returned to support chaining. This enables syntax such // as f := new(FieldVal).SetInt(2).Mul(f2) so that f = 2 * f2. // -// Preconditions: None -// Output Normalized: Yes -// Output Max Magnitude: 1 +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 func (f *FieldVal) SetInt(ui uint16) *FieldVal { f.Zero() f.n[0] = uint32(ui) @@ -242,9 +243,9 @@ func (f *FieldVal) SetInt(ui uint16) *FieldVal { // from a bool to numeric value in constant time and many constant-time // operations require a numeric value. // -// Preconditions: None -// Output Normalized: Yes if no overflow, no otherwise -// Output Max Magnitude: 1 +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 func (f *FieldVal) SetBytes(b *[32]byte) uint32 { // Pack the 256 total bits across the 10 uint32 words with a max of // 26-bits per word. This could be done with a couple of for loops, @@ -311,9 +312,9 @@ func (f *FieldVal) SetBytes(b *[32]byte) uint32 { // or it if is acceptable to use this function with the described truncation and // overflow behavior. // -// Preconditions: None -// Output Normalized: Yes if no overflow, no otherwise -// Output Max Magnitude: 1 +// Preconditions: None +// Output Normalized: Yes if no overflow, no otherwise +// Output Max Magnitude: 1 func (f *FieldVal) SetByteSlice(b []byte) bool { var b32 [32]byte b = b[:constantTimeMin(uint32(len(b)), 32)] @@ -328,9 +329,9 @@ func (f *FieldVal) SetByteSlice(b []byte) bool { // performs fast modular reduction over the secp256k1 prime by making use of the // special form of the prime in constant time. // -// Preconditions: None -// Output Normalized: Yes -// Output Max Magnitude: 1 +// Preconditions: None +// Output Normalized: Yes +// Output Max Magnitude: 1 func (f *FieldVal) Normalize() *FieldVal { // The field representation leaves 6 bits of overflow in each word so // intermediate calculations can be performed without needing to @@ -441,9 +442,9 @@ func (f *FieldVal) Normalize() *FieldVal { // to write directly into part of a larger buffer without needing a separate // allocation. // -// Preconditions: -// - The field value MUST be normalized -// - The target slice MUST have at least 32 bytes available +// Preconditions: +// - The field value MUST be normalized +// - The target slice MUST have at least 32 bytes available func (f *FieldVal) PutBytesUnchecked(b []byte) { // Unpack the 256 total bits from the 10 uint32 words with a max of // 26-bits per word. This could be done with a couple of for loops, @@ -495,8 +496,8 @@ func (f *FieldVal) PutBytesUnchecked(b []byte) { // array and returns that which can sometimes be more ergonomic in applications // that aren't concerned about an additional copy. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) PutBytes(b *[32]byte) { f.PutBytesUnchecked(b[:]) } @@ -508,8 +509,8 @@ func (f *FieldVal) PutBytes(b *[32]byte) { // allowing the caller to reuse a buffer or write directly into part of a larger // buffer. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) Bytes() *[32]byte { b := new([32]byte) f.PutBytesUnchecked(b[:]) @@ -524,8 +525,8 @@ func (f *FieldVal) Bytes() *[32]byte { // operations require a numeric value. See IsZero for the version that returns // a bool. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) IsZeroBit() uint32 { // The value can only be zero if no bits are set in any of the words. // This is a constant time implementation. @@ -538,8 +539,8 @@ func (f *FieldVal) IsZeroBit() uint32 { // IsZero returns whether or not the field value is equal to zero in constant // time. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) IsZero() bool { // The value can only be zero if no bits are set in any of the words. // This is a constant time implementation. @@ -557,8 +558,8 @@ func (f *FieldVal) IsZero() bool { // operations require a numeric value. See IsOne for the version that returns a // bool. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) IsOneBit() uint32 { // The value can only be one if the single lowest significant bit is set in // the first word and no other bits are set in any of the other words. @@ -572,8 +573,8 @@ func (f *FieldVal) IsOneBit() uint32 { // IsOne returns whether or not the field value is equal to one in constant // time. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) IsOne() bool { // The value can only be one if the single lowest significant bit is set in // the first word and no other bits are set in any of the other words. @@ -592,8 +593,8 @@ func (f *FieldVal) IsOne() bool { // operations require a numeric value. See IsOdd for the version that returns a // bool. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) IsOddBit() uint32 { // Only odd numbers have the bottom bit set. return f.n[0] & 1 @@ -602,8 +603,8 @@ func (f *FieldVal) IsOddBit() uint32 { // IsOdd returns whether or not the field value is an odd number in constant // time. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) IsOdd() bool { // Only odd numbers have the bottom bit set. return f.n[0]&1 == 1 @@ -612,8 +613,8 @@ func (f *FieldVal) IsOdd() bool { // Equals returns whether or not the two field values are the same in constant // time. // -// Preconditions: -// - Both field values being compared MUST be normalized +// Preconditions: +// - Both field values being compared MUST be normalized func (f *FieldVal) Equals(val *FieldVal) bool { // Xor only sets bits when they are different, so the two field values // can only be the same if no bits are set after xoring each word. @@ -633,10 +634,10 @@ func (f *FieldVal) Equals(val *FieldVal) bool { // The field value is returned to support chaining. This enables syntax like: // f.NegateVal(f2).AddInt(1) so that f = -f2 + 1. // -// Preconditions: -// - The max magnitude MUST be 63 -// Output Normalized: No -// Output Max Magnitude: Input magnitude + 1 +// Preconditions: +// - The max magnitude MUST be 63 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 func (f *FieldVal) NegateVal(val *FieldVal, magnitude uint32) *FieldVal { // Negation in the field is just the prime minus the value. However, // in order to allow negation against a field value without having to @@ -677,10 +678,10 @@ func (f *FieldVal) NegateVal(val *FieldVal, magnitude uint32) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f.Negate().AddInt(1) so that f = -f + 1. // -// Preconditions: -// - The max magnitude MUST be 63 -// Output Normalized: No -// Output Max Magnitude: Input magnitude + 1 +// Preconditions: +// - The max magnitude MUST be 63 +// Output Normalized: No +// Output Max Magnitude: Input magnitude + 1 func (f *FieldVal) Negate(magnitude uint32) *FieldVal { return f.NegateVal(f, magnitude) } @@ -692,10 +693,10 @@ func (f *FieldVal) Negate(magnitude uint32) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f.AddInt(1).Add(f2) so that f = f + 1 + f2. // -// Preconditions: -// - The field value MUST have a max magnitude of 63 -// Output Normalized: No -// Output Max Magnitude: Existing field magnitude + 1 +// Preconditions: +// - The field value MUST have a max magnitude of 63 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude + 1 func (f *FieldVal) AddInt(ui uint16) *FieldVal { // Since the field representation intentionally provides overflow bits, // it's ok to use carryless addition as the carry bit is safely part of @@ -711,10 +712,10 @@ func (f *FieldVal) AddInt(ui uint16) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f.Add(f2).AddInt(1) so that f = f + f2 + 1. // -// Preconditions: -// - The sum of the magnitudes of the two field values MUST be a max of 64 -// Output Normalized: No -// Output Max Magnitude: Sum of the magnitude of the two individual field values +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two individual field values func (f *FieldVal) Add(val *FieldVal) *FieldVal { // Since the field representation intentionally provides overflow bits, // it's ok to use carryless addition as the carry bit is safely part of @@ -740,10 +741,10 @@ func (f *FieldVal) Add(val *FieldVal) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f3.Add2(f, f2).AddInt(1) so that f3 = f + f2 + 1. // -// Preconditions: -// - The sum of the magnitudes of the two field values MUST be a max of 64 -// Output Normalized: No -// Output Max Magnitude: Sum of the magnitude of the two field values +// Preconditions: +// - The sum of the magnitudes of the two field values MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Sum of the magnitude of the two field values func (f *FieldVal) Add2(val *FieldVal, val2 *FieldVal) *FieldVal { // Since the field representation intentionally provides overflow bits, // it's ok to use carryless addition as the carry bit is safely part of @@ -772,10 +773,10 @@ func (f *FieldVal) Add2(val *FieldVal, val2 *FieldVal) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f.MulInt(2).Add(f2) so that f = 2 * f + f2. // -// Preconditions: -// - The field value magnitude multiplied by given val MUST be a max of 64 -// Output Normalized: No -// Output Max Magnitude: Existing field magnitude times the provided integer val +// Preconditions: +// - The field value magnitude multiplied by given val MUST be a max of 64 +// Output Normalized: No +// Output Max Magnitude: Existing field magnitude times the provided integer val func (f *FieldVal) MulInt(val uint8) *FieldVal { // Since each word of the field representation can hold up to // 32 - fieldBase extra bits which will be normalized out, it's safe @@ -807,10 +808,10 @@ func (f *FieldVal) MulInt(val uint8) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f.Mul(f2).AddInt(1) so that f = (f * f2) + 1. // -// Preconditions: -// - Both field values MUST have a max magnitude of 8 -// Output Normalized: No -// Output Max Magnitude: 1 +// Preconditions: +// - Both field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 func (f *FieldVal) Mul(val *FieldVal) *FieldVal { return f.Mul2(f, val) } @@ -824,10 +825,10 @@ func (f *FieldVal) Mul(val *FieldVal) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f3.Mul2(f, f2).AddInt(1) so that f3 = (f * f2) + 1. // -// Preconditions: -// - Both input field values MUST have a max magnitude of 8 -// Output Normalized: No -// Output Max Magnitude: 1 +// Preconditions: +// - Both input field values MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 func (f *FieldVal) Mul2(val *FieldVal, val2 *FieldVal) *FieldVal { // This could be done with a couple of for loops and an array to store // the intermediate terms, but this unrolled version is significantly @@ -1101,10 +1102,10 @@ func (f *FieldVal) Mul2(val *FieldVal, val2 *FieldVal) *FieldVal { // field must be a max of 8 to prevent overflow. The magnitude of the result // will be 1. // -// Preconditions: -// - The input field value MUST have a max magnitude of 8 -// Output Normalized: No -// Output Max Magnitude: 1 +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 func (f *FieldVal) SquareRootVal(val *FieldVal) bool { // This uses the Tonelli-Shanks method for calculating the square root of // the value when it exists. The key principles of the method follow. @@ -1156,7 +1157,7 @@ func (f *FieldVal) SquareRootVal(val *FieldVal) bool { // 10111111 11111111 11111111 00001100 // // Notice that can be broken up into three windows of consecutive 1s (in - // order of least to most signifcant) as: + // order of least to most significant) as: // // 6-bit window with two bits set (bits 4, 5, 6, 7 unset) // 23-bit window with 22 bits set (bit 30 unset) @@ -1262,10 +1263,10 @@ func (f *FieldVal) SquareRootVal(val *FieldVal) bool { // The field value is returned to support chaining. This enables syntax like: // f.Square().Mul(f2) so that f = f^2 * f2. // -// Preconditions: -// - The field value MUST have a max magnitude of 8 -// Output Normalized: No -// Output Max Magnitude: 1 +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 func (f *FieldVal) Square() *FieldVal { return f.SquareVal(f) } @@ -1278,10 +1279,10 @@ func (f *FieldVal) Square() *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f3.SquareVal(f).Mul(f) so that f3 = f^2 * f = f^3. // -// Preconditions: -// - The input field value MUST have a max magnitude of 8 -// Output Normalized: No -// Output Max Magnitude: 1 +// Preconditions: +// - The input field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 func (f *FieldVal) SquareVal(val *FieldVal) *FieldVal { // This could be done with a couple of for loops and an array to store // the intermediate terms, but this unrolled version is significantly @@ -1503,10 +1504,10 @@ func (f *FieldVal) SquareVal(val *FieldVal) *FieldVal { // The field value is returned to support chaining. This enables syntax like: // f.Inverse().Mul(f2) so that f = f^-1 * f2. // -// Preconditions: -// - The field value MUST have a max magnitude of 8 -// Output Normalized: No -// Output Max Magnitude: 1 +// Preconditions: +// - The field value MUST have a max magnitude of 8 +// Output Normalized: No +// Output Max Magnitude: 1 func (f *FieldVal) Inverse() *FieldVal { // Fermat's little theorem states that for a nonzero number a and prime // prime p, a^(p-1) = 1 (mod p). Since the multiplicative inverse is @@ -1614,8 +1615,8 @@ func (f *FieldVal) Inverse() *FieldVal { // IsGtOrEqPrimeMinusOrder returns whether or not the field value exceeds the // group order divided by 2 in constant time. // -// Preconditions: -// - The field value MUST be normalized +// Preconditions: +// - The field value MUST be normalized func (f *FieldVal) IsGtOrEqPrimeMinusOrder() bool { // The secp256k1 prime is equivalent to 2^256 - 4294968273 and the group // order is 2^256 - 432420386565659656852420866394968145599. Thus, diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go deleted file mode 100644 index fa613deb7..000000000 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/genstatics.go +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (c) 2014-2015 The btcsuite developers -// Copyright (c) 2015-2021 The Decred developers -// Use of this source code is governed by an ISC -// license that can be found in the LICENSE file. - -// This file is ignored during the regular build due to the following build tag. -// This build tag is set during go generate. -//go:build gensecp256k1 -// +build gensecp256k1 - -package secp256k1 - -// References: -// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) - -import ( - "encoding/binary" - "math/big" -) - -// compressedBytePoints are dummy points used so the code which generates the -// real values can compile. -var compressedBytePoints = "" - -// SerializedBytePoints returns a serialized byte slice which contains all of -// the possible points per 8-bit window. This is used to when generating -// compressedbytepoints.go. -func SerializedBytePoints() []byte { - // Calculate G^(2^i) for i in 0..255. These are used to avoid recomputing - // them for each digit of the 8-bit windows. - doublingPoints := make([]JacobianPoint, curveParams.BitSize) - var q JacobianPoint - bigAffineToJacobian(curveParams.Gx, curveParams.Gy, &q) - for i := 0; i < curveParams.BitSize; i++ { - // Q = 2*Q. - doublingPoints[i] = q - DoubleNonConst(&q, &q) - } - - // Separate the bits into byte-sized windows. - curveByteSize := curveParams.BitSize / 8 - serialized := make([]byte, curveByteSize*256*2*10*4) - offset := 0 - for byteNum := 0; byteNum < curveByteSize; byteNum++ { - // Grab the 8 bits that make up this byte from doubling points. - startingBit := 8 * (curveByteSize - byteNum - 1) - windowPoints := doublingPoints[startingBit : startingBit+8] - - // Compute all points in this window, convert them to affine, and - // serialize them. - for i := 0; i < 256; i++ { - var point JacobianPoint - for bit := 0; bit < 8; bit++ { - if i>>uint(bit)&1 == 1 { - AddNonConst(&point, &windowPoints[bit], &point) - } - } - point.ToAffine() - - for i := 0; i < len(point.X.n); i++ { - binary.LittleEndian.PutUint32(serialized[offset:], point.X.n[i]) - offset += 4 - } - for i := 0; i < len(point.Y.n); i++ { - binary.LittleEndian.PutUint32(serialized[offset:], point.Y.n[i]) - offset += 4 - } - } - } - - return serialized -} - -// sqrt returns the square root of the provided big integer using Newton's -// method. It's only compiled and used during generation of pre-computed -// values, so speed is not a huge concern. -func sqrt(n *big.Int) *big.Int { - // Initial guess = 2^(log_2(n)/2) - guess := big.NewInt(2) - guess.Exp(guess, big.NewInt(int64(n.BitLen()/2)), nil) - - // Now refine using Newton's method. - big2 := big.NewInt(2) - prevGuess := big.NewInt(0) - for { - prevGuess.Set(guess) - guess.Add(guess, new(big.Int).Div(n, guess)) - guess.Div(guess, big2) - if guess.Cmp(prevGuess) == 0 { - break - } - } - return guess -} - -// EndomorphismVectors runs the first 3 steps of algorithm 3.74 from [GECC] to -// generate the linearly independent vectors needed to generate a balanced -// length-two representation of a multiplier such that k = k1 + k2λ (mod N) and -// returns them. Since the values will always be the same given the fact that N -// and λ are fixed, the final results can be accelerated by storing the -// precomputed values. -func EndomorphismVectors() (a1, b1, a2, b2 *big.Int) { - bigMinus1 := big.NewInt(-1) - - // This section uses an extended Euclidean algorithm to generate a - // sequence of equations: - // s[i] * N + t[i] * λ = r[i] - - nSqrt := sqrt(curveParams.N) - u, v := new(big.Int).Set(curveParams.N), new(big.Int).Set(endomorphismLambda) - x1, y1 := big.NewInt(1), big.NewInt(0) - x2, y2 := big.NewInt(0), big.NewInt(1) - q, r := new(big.Int), new(big.Int) - qu, qx1, qy1 := new(big.Int), new(big.Int), new(big.Int) - s, t := new(big.Int), new(big.Int) - ri, ti := new(big.Int), new(big.Int) - a1, b1, a2, b2 = new(big.Int), new(big.Int), new(big.Int), new(big.Int) - found, oneMore := false, false - for u.Sign() != 0 { - // q = v/u - q.Div(v, u) - - // r = v - q*u - qu.Mul(q, u) - r.Sub(v, qu) - - // s = x2 - q*x1 - qx1.Mul(q, x1) - s.Sub(x2, qx1) - - // t = y2 - q*y1 - qy1.Mul(q, y1) - t.Sub(y2, qy1) - - // v = u, u = r, x2 = x1, x1 = s, y2 = y1, y1 = t - v.Set(u) - u.Set(r) - x2.Set(x1) - x1.Set(s) - y2.Set(y1) - y1.Set(t) - - // As soon as the remainder is less than the sqrt of n, the - // values of a1 and b1 are known. - if !found && r.Cmp(nSqrt) < 0 { - // When this condition executes ri and ti represent the - // r[i] and t[i] values such that i is the greatest - // index for which r >= sqrt(n). Meanwhile, the current - // r and t values are r[i+1] and t[i+1], respectively. - - // a1 = r[i+1], b1 = -t[i+1] - a1.Set(r) - b1.Mul(t, bigMinus1) - found = true - oneMore = true - - // Skip to the next iteration so ri and ti are not - // modified. - continue - - } else if oneMore { - // When this condition executes ri and ti still - // represent the r[i] and t[i] values while the current - // r and t are r[i+2] and t[i+2], respectively. - - // sum1 = r[i]^2 + t[i]^2 - rSquared := new(big.Int).Mul(ri, ri) - tSquared := new(big.Int).Mul(ti, ti) - sum1 := new(big.Int).Add(rSquared, tSquared) - - // sum2 = r[i+2]^2 + t[i+2]^2 - r2Squared := new(big.Int).Mul(r, r) - t2Squared := new(big.Int).Mul(t, t) - sum2 := new(big.Int).Add(r2Squared, t2Squared) - - // if (r[i]^2 + t[i]^2) <= (r[i+2]^2 + t[i+2]^2) - if sum1.Cmp(sum2) <= 0 { - // a2 = r[i], b2 = -t[i] - a2.Set(ri) - b2.Mul(ti, bigMinus1) - } else { - // a2 = r[i+2], b2 = -t[i+2] - a2.Set(r) - b2.Mul(t, bigMinus1) - } - - // All done. - break - } - - ri.Set(r) - ti.Set(t) - } - - return a1, b1, a2, b2 -} diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go index 9f975b52a..91c3d3776 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go @@ -1,5 +1,5 @@ // Copyright 2015 The btcsuite developers -// Copyright (c) 2015-2021 The Decred developers +// Copyright (c) 2015-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -8,17 +8,21 @@ package secp256k1 import ( "compress/zlib" "encoding/base64" - "encoding/binary" "io" "strings" "sync" ) -//go:generate go run -tags gensecp256k1 genprecomps.go +//go:generate go run genprecomps.go // bytePointTable describes a table used to house pre-computed values for // accelerating scalar base multiplication. -type bytePointTable [32][256][2]FieldVal +type bytePointTable [32][256]JacobianPoint + +// compressedBytePointsFn is set to a real function by the code generation to +// return the compressed pre-computed values for accelerating scalar base +// multiplication. +var compressedBytePointsFn func() string // s256BytePoints houses pre-computed values used to accelerate scalar base // multiplication such that they are only loaded on first use. @@ -38,10 +42,10 @@ var s256BytePoints = func() func() *bytePointTable { var data *bytePointTable mustLoadBytePoints := func() { // There will be no byte points to load when generating them. - bp := compressedBytePoints - if len(bp) == 0 { + if compressedBytePointsFn == nil { return } + bp := compressedBytePointsFn() // Decompress the pre-computed table used to accelerate scalar base // multiplication. @@ -62,16 +66,12 @@ var s256BytePoints = func() func() *bytePointTable { for byteNum := 0; byteNum < len(bytePoints); byteNum++ { // All points in this window. for i := 0; i < len(bytePoints[byteNum]); i++ { - px := &bytePoints[byteNum][i][0] - py := &bytePoints[byteNum][i][1] - for i := 0; i < len(px.n); i++ { - px.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) - offset += 4 - } - for i := 0; i < len(py.n); i++ { - py.n[i] = binary.LittleEndian.Uint32(serialized[offset:]) - offset += 4 - } + p := &bytePoints[byteNum][i] + p.X.SetByteSlice(serialized[offset:]) + offset += 32 + p.Y.SetByteSlice(serialized[offset:]) + offset += 32 + p.Z.SetInt(1) } } data = &bytePoints diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go index 8125d9a99..f66496ed5 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 The Decred developers +// Copyright (c) 2020-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -100,7 +100,7 @@ var ( // arithmetic over the secp256k1 group order. This means all arithmetic is // performed modulo: // -// 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 +// 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 // // It only implements the arithmetic needed for elliptic curve operations, // however, the operations that are not implemented can typically be worked @@ -174,6 +174,19 @@ func (s *ModNScalar) Zero() { s.n[7] = 0 } +// IsZeroBit returns 1 when the scalar is equal to zero or 0 otherwise in +// constant time. +// +// Note that a bool is not used here because it is not possible in Go to convert +// from a bool to numeric value in constant time and many constant-time +// operations require a numeric value. See IsZero for the version that returns +// a bool. +func (s *ModNScalar) IsZeroBit() uint32 { + // The scalar can only be zero if no bits are set in any of the words. + bits := s.n[0] | s.n[1] | s.n[2] | s.n[3] | s.n[4] | s.n[5] | s.n[6] | s.n[7] + return constantTimeEq(bits, 0) +} + // IsZero returns whether or not the scalar is equal to zero in constant time. func (s *ModNScalar) IsZero() bool { // The scalar can only be zero if no bits are set in any of the words. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go index 3590346c6..3ca5b7c2f 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go @@ -1,13 +1,12 @@ // Copyright (c) 2013-2014 The btcsuite developers -// Copyright (c) 2015-2020 The Decred developers +// Copyright (c) 2015-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. package secp256k1 import ( - "crypto/ecdsa" - "crypto/rand" + csprng "crypto/rand" ) // PrivateKey provides facilities for working with secp256k1 private keys within @@ -40,14 +39,27 @@ func PrivKeyFromBytes(privKeyBytes []byte) *PrivateKey { return &privKey } -// GeneratePrivateKey returns a private key that is suitable for use with -// secp256k1. +// GeneratePrivateKey generates and returns a new cryptographically secure +// private key that is suitable for use with secp256k1. func GeneratePrivateKey() (*PrivateKey, error) { - key, err := ecdsa.GenerateKey(S256(), rand.Reader) - if err != nil { - return nil, err + // The group order is close enough to 2^256 that there is only roughly a 1 + // in 2^128 chance of generating an invalid private key, so this loop will + // virtually never run more than a single iteration in practice. + var key PrivateKey + var b32 [32]byte + for valid := false; !valid; { + if _, err := csprng.Read(b32[:]); err != nil { + return nil, err + } + + // The private key is only valid when it is in the range [1, N-1], where + // N is the order of the curve. + overflow := key.Key.SetBytes(&b32) + valid = (key.Key.IsZeroBit() | overflow) == 0 } - return PrivKeyFromBytes(key.D.Bytes()), nil + zeroArray32(&b32) + + return &key, nil } // PubKey computes and returns the public key corresponding to this private key. diff --git a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go index 67165833f..54c54be5f 100644 --- a/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go +++ b/vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2014 The btcsuite developers -// Copyright (c) 2015-2021 The Decred developers +// Copyright (c) 2015-2022 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -92,11 +92,16 @@ func NewPublicKey(x, y *FieldVal) *PublicKey { // hybrid formats as follows: // // Compressed: -// <32-byte X coordinate> +// +// <32-byte X coordinate> +// // Uncompressed: -// <32-byte X coordinate><32-byte Y coordinate> +// +// <32-byte X coordinate><32-byte Y coordinate> +// // Hybrid: -// <32-byte X coordinate><32-byte Y coordinate> +// +// <32-byte X coordinate><32-byte Y coordinate> // // NOTE: The hybrid format makes little sense in practice an therefore this // package will not produce public keys serialized in this format. However, @@ -209,9 +214,9 @@ func (p PublicKey) SerializeCompressed() []byte { return b[:] } -// IsEqual compares this PublicKey instance to the one passed, returning true if -// both PublicKeys are equivalent. A PublicKey is equivalent to another, if they -// both have the same X and Y coordinate. +// IsEqual compares this public key instance to the one passed, returning true +// if both public keys are equivalent. A public key is equivalent to another, +// if they both have the same X and Y coordinates. func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool { return p.x.Equals(&otherPubKey.x) && p.y.Equals(&otherPubKey.y) } diff --git a/vendor/github.com/docker/go-units/size.go b/vendor/github.com/docker/go-units/size.go index 85f6ab071..c245a8951 100644 --- a/vendor/github.com/docker/go-units/size.go +++ b/vendor/github.com/docker/go-units/size.go @@ -2,7 +2,6 @@ package units import ( "fmt" - "regexp" "strconv" "strings" ) @@ -26,16 +25,17 @@ const ( PiB = 1024 * TiB ) -type unitMap map[string]int64 +type unitMap map[byte]int64 var ( - decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB} - binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB} - sizeRegex = regexp.MustCompile(`^(\d+(\.\d+)*) ?([kKmMgGtTpP])?[iI]?[bB]?$`) + decimalMap = unitMap{'k': KB, 'm': MB, 'g': GB, 't': TB, 'p': PB} + binaryMap = unitMap{'k': KiB, 'm': MiB, 'g': GiB, 't': TiB, 'p': PiB} ) -var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} -var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} +var ( + decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} + binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} +) func getSizeAndUnit(size float64, base float64, _map []string) (float64, string) { i := 0 @@ -89,20 +89,66 @@ func RAMInBytes(size string) (int64, error) { // Parses the human-readable size string into the amount it represents. func parseSize(sizeStr string, uMap unitMap) (int64, error) { - matches := sizeRegex.FindStringSubmatch(sizeStr) - if len(matches) != 4 { + // TODO: rewrite to use strings.Cut if there's a space + // once Go < 1.18 is deprecated. + sep := strings.LastIndexAny(sizeStr, "01234567890. ") + if sep == -1 { + // There should be at least a digit. return -1, fmt.Errorf("invalid size: '%s'", sizeStr) } + var num, sfx string + if sizeStr[sep] != ' ' { + num = sizeStr[:sep+1] + sfx = sizeStr[sep+1:] + } else { + // Omit the space separator. + num = sizeStr[:sep] + sfx = sizeStr[sep+1:] + } - size, err := strconv.ParseFloat(matches[1], 64) + size, err := strconv.ParseFloat(num, 64) if err != nil { return -1, err } + // Backward compatibility: reject negative sizes. + if size < 0 { + return -1, fmt.Errorf("invalid size: '%s'", sizeStr) + } - unitPrefix := strings.ToLower(matches[3]) - if mul, ok := uMap[unitPrefix]; ok { + if len(sfx) == 0 { + return int64(size), nil + } + + // Process the suffix. + + if len(sfx) > 3 { // Too long. + goto badSuffix + } + sfx = strings.ToLower(sfx) + // Trivial case: b suffix. + if sfx[0] == 'b' { + if len(sfx) > 1 { // no extra characters allowed after b. + goto badSuffix + } + return int64(size), nil + } + // A suffix from the map. + if mul, ok := uMap[sfx[0]]; ok { size *= float64(mul) + } else { + goto badSuffix + } + + // The suffix may have extra "b" or "ib" (e.g. KiB or MB). + switch { + case len(sfx) == 2 && sfx[1] != 'b': + goto badSuffix + case len(sfx) == 3 && sfx[1:] != "ib": + goto badSuffix } return int64(size), nil + +badSuffix: + return -1, fmt.Errorf("invalid suffix: '%s'", sfx) } diff --git a/vendor/github.com/gogo/protobuf/io/full.go b/vendor/github.com/gogo/protobuf/io/full.go deleted file mode 100644 index 550726a32..000000000 --- a/vendor/github.com/gogo/protobuf/io/full.go +++ /dev/null @@ -1,102 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// 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. -// -// 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. - -package io - -import ( - "github.com/gogo/protobuf/proto" - "io" -) - -func NewFullWriter(w io.Writer) WriteCloser { - return &fullWriter{w, nil} -} - -type fullWriter struct { - w io.Writer - buffer []byte -} - -func (this *fullWriter) WriteMsg(msg proto.Message) (err error) { - var data []byte - if m, ok := msg.(marshaler); ok { - n, ok := getSize(m) - if !ok { - data, err = proto.Marshal(msg) - if err != nil { - return err - } - } - if n >= len(this.buffer) { - this.buffer = make([]byte, n) - } - _, err = m.MarshalTo(this.buffer) - if err != nil { - return err - } - data = this.buffer[:n] - } else { - data, err = proto.Marshal(msg) - if err != nil { - return err - } - } - _, err = this.w.Write(data) - return err -} - -func (this *fullWriter) Close() error { - if closer, ok := this.w.(io.Closer); ok { - return closer.Close() - } - return nil -} - -type fullReader struct { - r io.Reader - buf []byte -} - -func NewFullReader(r io.Reader, maxSize int) ReadCloser { - return &fullReader{r, make([]byte, maxSize)} -} - -func (this *fullReader) ReadMsg(msg proto.Message) error { - length, err := this.r.Read(this.buf) - if err != nil { - return err - } - return proto.Unmarshal(this.buf[:length], msg) -} - -func (this *fullReader) Close() error { - if closer, ok := this.r.(io.Closer); ok { - return closer.Close() - } - return nil -} diff --git a/vendor/github.com/gogo/protobuf/io/io.go b/vendor/github.com/gogo/protobuf/io/io.go deleted file mode 100644 index 6dca519a1..000000000 --- a/vendor/github.com/gogo/protobuf/io/io.go +++ /dev/null @@ -1,70 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// 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. -// -// 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. - -package io - -import ( - "github.com/gogo/protobuf/proto" - "io" -) - -type Writer interface { - WriteMsg(proto.Message) error -} - -type WriteCloser interface { - Writer - io.Closer -} - -type Reader interface { - ReadMsg(msg proto.Message) error -} - -type ReadCloser interface { - Reader - io.Closer -} - -type marshaler interface { - MarshalTo(data []byte) (n int, err error) -} - -func getSize(v interface{}) (int, bool) { - if sz, ok := v.(interface { - Size() (n int) - }); ok { - return sz.Size(), true - } else if sz, ok := v.(interface { - ProtoSize() (n int) - }); ok { - return sz.ProtoSize(), true - } else { - return 0, false - } -} diff --git a/vendor/github.com/gogo/protobuf/io/uint32.go b/vendor/github.com/gogo/protobuf/io/uint32.go deleted file mode 100644 index 233b90924..000000000 --- a/vendor/github.com/gogo/protobuf/io/uint32.go +++ /dev/null @@ -1,138 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// 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. -// -// 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. - -package io - -import ( - "encoding/binary" - "io" - - "github.com/gogo/protobuf/proto" -) - -const uint32BinaryLen = 4 - -func NewUint32DelimitedWriter(w io.Writer, byteOrder binary.ByteOrder) WriteCloser { - return &uint32Writer{w, byteOrder, nil, make([]byte, uint32BinaryLen)} -} - -func NewSizeUint32DelimitedWriter(w io.Writer, byteOrder binary.ByteOrder, size int) WriteCloser { - return &uint32Writer{w, byteOrder, make([]byte, size), make([]byte, uint32BinaryLen)} -} - -type uint32Writer struct { - w io.Writer - byteOrder binary.ByteOrder - buffer []byte - lenBuf []byte -} - -func (this *uint32Writer) writeFallback(msg proto.Message) error { - data, err := proto.Marshal(msg) - if err != nil { - return err - } - - length := uint32(len(data)) - this.byteOrder.PutUint32(this.lenBuf, length) - if _, err = this.w.Write(this.lenBuf); err != nil { - return err - } - _, err = this.w.Write(data) - return err -} - -func (this *uint32Writer) WriteMsg(msg proto.Message) error { - m, ok := msg.(marshaler) - if !ok { - return this.writeFallback(msg) - } - - n, ok := getSize(m) - if !ok { - return this.writeFallback(msg) - } - - size := n + uint32BinaryLen - if size > len(this.buffer) { - this.buffer = make([]byte, size) - } - - this.byteOrder.PutUint32(this.buffer, uint32(n)) - if _, err := m.MarshalTo(this.buffer[uint32BinaryLen:]); err != nil { - return err - } - - _, err := this.w.Write(this.buffer[:size]) - return err -} - -func (this *uint32Writer) Close() error { - if closer, ok := this.w.(io.Closer); ok { - return closer.Close() - } - return nil -} - -type uint32Reader struct { - r io.Reader - byteOrder binary.ByteOrder - lenBuf []byte - buf []byte - maxSize int -} - -func NewUint32DelimitedReader(r io.Reader, byteOrder binary.ByteOrder, maxSize int) ReadCloser { - return &uint32Reader{r, byteOrder, make([]byte, 4), nil, maxSize} -} - -func (this *uint32Reader) ReadMsg(msg proto.Message) error { - if _, err := io.ReadFull(this.r, this.lenBuf); err != nil { - return err - } - length32 := this.byteOrder.Uint32(this.lenBuf) - length := int(length32) - if length < 0 || length > this.maxSize { - return io.ErrShortBuffer - } - if length > len(this.buf) { - this.buf = make([]byte, length) - } - _, err := io.ReadFull(this.r, this.buf[:length]) - if err != nil { - return err - } - return proto.Unmarshal(this.buf[:length], msg) -} - -func (this *uint32Reader) Close() error { - if closer, ok := this.r.(io.Closer); ok { - return closer.Close() - } - return nil -} diff --git a/vendor/github.com/gogo/protobuf/io/varint.go b/vendor/github.com/gogo/protobuf/io/varint.go deleted file mode 100644 index e81e296e4..000000000 --- a/vendor/github.com/gogo/protobuf/io/varint.go +++ /dev/null @@ -1,133 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// 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. -// -// 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. - -package io - -import ( - "bufio" - "encoding/binary" - "errors" - "github.com/gogo/protobuf/proto" - "io" -) - -var ( - errSmallBuffer = errors.New("Buffer Too Small") - errLargeValue = errors.New("Value is Larger than 64 bits") -) - -func NewDelimitedWriter(w io.Writer) WriteCloser { - return &varintWriter{w, make([]byte, binary.MaxVarintLen64), nil} -} - -type varintWriter struct { - w io.Writer - lenBuf []byte - buffer []byte -} - -func (this *varintWriter) WriteMsg(msg proto.Message) (err error) { - var data []byte - if m, ok := msg.(marshaler); ok { - n, ok := getSize(m) - if ok { - if n+binary.MaxVarintLen64 >= len(this.buffer) { - this.buffer = make([]byte, n+binary.MaxVarintLen64) - } - lenOff := binary.PutUvarint(this.buffer, uint64(n)) - _, err = m.MarshalTo(this.buffer[lenOff:]) - if err != nil { - return err - } - _, err = this.w.Write(this.buffer[:lenOff+n]) - return err - } - } - - // fallback - data, err = proto.Marshal(msg) - if err != nil { - return err - } - length := uint64(len(data)) - n := binary.PutUvarint(this.lenBuf, length) - _, err = this.w.Write(this.lenBuf[:n]) - if err != nil { - return err - } - _, err = this.w.Write(data) - return err -} - -func (this *varintWriter) Close() error { - if closer, ok := this.w.(io.Closer); ok { - return closer.Close() - } - return nil -} - -func NewDelimitedReader(r io.Reader, maxSize int) ReadCloser { - var closer io.Closer - if c, ok := r.(io.Closer); ok { - closer = c - } - return &varintReader{bufio.NewReader(r), nil, maxSize, closer} -} - -type varintReader struct { - r *bufio.Reader - buf []byte - maxSize int - closer io.Closer -} - -func (this *varintReader) ReadMsg(msg proto.Message) error { - length64, err := binary.ReadUvarint(this.r) - if err != nil { - return err - } - length := int(length64) - if length < 0 || length > this.maxSize { - return io.ErrShortBuffer - } - if len(this.buf) < length { - this.buf = make([]byte, length) - } - buf := this.buf[:length] - if _, err := io.ReadFull(this.r, buf); err != nil { - return err - } - return proto.Unmarshal(buf, msg) -} - -func (this *varintReader) Close() error { - if this.closer != nil { - return this.closer.Close() - } - return nil -} diff --git a/vendor/github.com/golang/mock/mockgen/mockgen.go b/vendor/github.com/golang/mock/mockgen/mockgen.go new file mode 100644 index 000000000..50487070e --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/mockgen.go @@ -0,0 +1,701 @@ +// Copyright 2010 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// MockGen generates mock implementations of Go interfaces. +package main + +// TODO: This does not support recursive embedded interfaces. +// TODO: This does not support embedding package-local interfaces in a separate file. + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "go/token" + "io" + "io/ioutil" + "log" + "os" + "os/exec" + "path" + "path/filepath" + "sort" + "strconv" + "strings" + "unicode" + + "github.com/golang/mock/mockgen/model" + + "golang.org/x/mod/modfile" + toolsimports "golang.org/x/tools/imports" +) + +const ( + gomockImportPath = "github.com/golang/mock/gomock" +) + +var ( + version = "" + commit = "none" + date = "unknown" +) + +var ( + source = flag.String("source", "", "(source mode) Input Go source file; enables source mode.") + destination = flag.String("destination", "", "Output file; defaults to stdout.") + mockNames = flag.String("mock_names", "", "Comma-separated interfaceName=mockName pairs of explicit mock names to use. Mock names default to 'Mock'+ interfaceName suffix.") + packageOut = flag.String("package", "", "Package of the generated code; defaults to the package of the input with a 'mock_' prefix.") + selfPackage = flag.String("self_package", "", "The full package import path for the generated code. The purpose of this flag is to prevent import cycles in the generated code by trying to include its own package. This can happen if the mock's package is set to one of its inputs (usually the main one) and the output is stdio so mockgen cannot detect the final output package. Setting this flag will then tell mockgen which import to exclude.") + writePkgComment = flag.Bool("write_package_comment", true, "Writes package documentation comment (godoc) if true.") + copyrightFile = flag.String("copyright_file", "", "Copyright file used to add copyright header") + + debugParser = flag.Bool("debug_parser", false, "Print out parser results only.") + showVersion = flag.Bool("version", false, "Print version.") +) + +func main() { + flag.Usage = usage + flag.Parse() + + if *showVersion { + printVersion() + return + } + + var pkg *model.Package + var err error + var packageName string + if *source != "" { + pkg, err = sourceMode(*source) + } else { + if flag.NArg() != 2 { + usage() + log.Fatal("Expected exactly two arguments") + } + packageName = flag.Arg(0) + interfaces := strings.Split(flag.Arg(1), ",") + if packageName == "." { + dir, err := os.Getwd() + if err != nil { + log.Fatalf("Get current directory failed: %v", err) + } + packageName, err = packageNameOfDir(dir) + if err != nil { + log.Fatalf("Parse package name failed: %v", err) + } + } + pkg, err = reflectMode(packageName, interfaces) + } + if err != nil { + log.Fatalf("Loading input failed: %v", err) + } + + if *debugParser { + pkg.Print(os.Stdout) + return + } + + dst := os.Stdout + if len(*destination) > 0 { + if err := os.MkdirAll(filepath.Dir(*destination), os.ModePerm); err != nil { + log.Fatalf("Unable to create directory: %v", err) + } + f, err := os.Create(*destination) + if err != nil { + log.Fatalf("Failed opening destination file: %v", err) + } + defer f.Close() + dst = f + } + + outputPackageName := *packageOut + if outputPackageName == "" { + // pkg.Name in reflect mode is the base name of the import path, + // which might have characters that are illegal to have in package names. + outputPackageName = "mock_" + sanitize(pkg.Name) + } + + // outputPackagePath represents the fully qualified name of the package of + // the generated code. Its purposes are to prevent the module from importing + // itself and to prevent qualifying type names that come from its own + // package (i.e. if there is a type called X then we want to print "X" not + // "package.X" since "package" is this package). This can happen if the mock + // is output into an already existing package. + outputPackagePath := *selfPackage + if outputPackagePath == "" && *destination != "" { + dstPath, err := filepath.Abs(filepath.Dir(*destination)) + if err == nil { + pkgPath, err := parsePackageImport(dstPath) + if err == nil { + outputPackagePath = pkgPath + } else { + log.Println("Unable to infer -self_package from destination file path:", err) + } + } else { + log.Println("Unable to determine destination file path:", err) + } + } + + g := new(generator) + if *source != "" { + g.filename = *source + } else { + g.srcPackage = packageName + g.srcInterfaces = flag.Arg(1) + } + g.destination = *destination + + if *mockNames != "" { + g.mockNames = parseMockNames(*mockNames) + } + if *copyrightFile != "" { + header, err := ioutil.ReadFile(*copyrightFile) + if err != nil { + log.Fatalf("Failed reading copyright file: %v", err) + } + + g.copyrightHeader = string(header) + } + if err := g.Generate(pkg, outputPackageName, outputPackagePath); err != nil { + log.Fatalf("Failed generating mock: %v", err) + } + if _, err := dst.Write(g.Output()); err != nil { + log.Fatalf("Failed writing to destination: %v", err) + } +} + +func parseMockNames(names string) map[string]string { + mocksMap := make(map[string]string) + for _, kv := range strings.Split(names, ",") { + parts := strings.SplitN(kv, "=", 2) + if len(parts) != 2 || parts[1] == "" { + log.Fatalf("bad mock names spec: %v", kv) + } + mocksMap[parts[0]] = parts[1] + } + return mocksMap +} + +func usage() { + _, _ = io.WriteString(os.Stderr, usageText) + flag.PrintDefaults() +} + +const usageText = `mockgen has two modes of operation: source and reflect. + +Source mode generates mock interfaces from a source file. +It is enabled by using the -source flag. Other flags that +may be useful in this mode are -imports and -aux_files. +Example: + mockgen -source=foo.go [other options] + +Reflect mode generates mock interfaces by building a program +that uses reflection to understand interfaces. It is enabled +by passing two non-flag arguments: an import path, and a +comma-separated list of symbols. +Example: + mockgen database/sql/driver Conn,Driver + +` + +type generator struct { + buf bytes.Buffer + indent string + mockNames map[string]string // may be empty + filename string // may be empty + destination string // may be empty + srcPackage, srcInterfaces string // may be empty + copyrightHeader string + + packageMap map[string]string // map from import path to package name +} + +func (g *generator) p(format string, args ...interface{}) { + fmt.Fprintf(&g.buf, g.indent+format+"\n", args...) +} + +func (g *generator) in() { + g.indent += "\t" +} + +func (g *generator) out() { + if len(g.indent) > 0 { + g.indent = g.indent[0 : len(g.indent)-1] + } +} + +// sanitize cleans up a string to make a suitable package name. +func sanitize(s string) string { + t := "" + for _, r := range s { + if t == "" { + if unicode.IsLetter(r) || r == '_' { + t += string(r) + continue + } + } else { + if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { + t += string(r) + continue + } + } + t += "_" + } + if t == "_" { + t = "x" + } + return t +} + +func (g *generator) Generate(pkg *model.Package, outputPkgName string, outputPackagePath string) error { + if outputPkgName != pkg.Name && *selfPackage == "" { + // reset outputPackagePath if it's not passed in through -self_package + outputPackagePath = "" + } + + if g.copyrightHeader != "" { + lines := strings.Split(g.copyrightHeader, "\n") + for _, line := range lines { + g.p("// %s", line) + } + g.p("") + } + + g.p("// Code generated by MockGen. DO NOT EDIT.") + if g.filename != "" { + g.p("// Source: %v", g.filename) + } else { + g.p("// Source: %v (interfaces: %v)", g.srcPackage, g.srcInterfaces) + } + g.p("") + + // Get all required imports, and generate unique names for them all. + im := pkg.Imports() + im[gomockImportPath] = true + + // Only import reflect if it's used. We only use reflect in mocked methods + // so only import if any of the mocked interfaces have methods. + for _, intf := range pkg.Interfaces { + if len(intf.Methods) > 0 { + im["reflect"] = true + break + } + } + + // Sort keys to make import alias generation predictable + sortedPaths := make([]string, len(im)) + x := 0 + for pth := range im { + sortedPaths[x] = pth + x++ + } + sort.Strings(sortedPaths) + + packagesName := createPackageMap(sortedPaths) + + g.packageMap = make(map[string]string, len(im)) + localNames := make(map[string]bool, len(im)) + for _, pth := range sortedPaths { + base, ok := packagesName[pth] + if !ok { + base = sanitize(path.Base(pth)) + } + + // Local names for an imported package can usually be the basename of the import path. + // A couple of situations don't permit that, such as duplicate local names + // (e.g. importing "html/template" and "text/template"), or where the basename is + // a keyword (e.g. "foo/case"). + // try base0, base1, ... + pkgName := base + i := 0 + for localNames[pkgName] || token.Lookup(pkgName).IsKeyword() { + pkgName = base + strconv.Itoa(i) + i++ + } + + // Avoid importing package if source pkg == output pkg + if pth == pkg.PkgPath && outputPackagePath == pkg.PkgPath { + continue + } + + g.packageMap[pth] = pkgName + localNames[pkgName] = true + } + + if *writePkgComment { + g.p("// Package %v is a generated GoMock package.", outputPkgName) + } + g.p("package %v", outputPkgName) + g.p("") + g.p("import (") + g.in() + for pkgPath, pkgName := range g.packageMap { + if pkgPath == outputPackagePath { + continue + } + g.p("%v %q", pkgName, pkgPath) + } + for _, pkgPath := range pkg.DotImports { + g.p(". %q", pkgPath) + } + g.out() + g.p(")") + + for _, intf := range pkg.Interfaces { + if err := g.GenerateMockInterface(intf, outputPackagePath); err != nil { + return err + } + } + + return nil +} + +// The name of the mock type to use for the given interface identifier. +func (g *generator) mockName(typeName string) string { + if mockName, ok := g.mockNames[typeName]; ok { + return mockName + } + + return "Mock" + typeName +} + +func (g *generator) GenerateMockInterface(intf *model.Interface, outputPackagePath string) error { + mockType := g.mockName(intf.Name) + + g.p("") + g.p("// %v is a mock of %v interface.", mockType, intf.Name) + g.p("type %v struct {", mockType) + g.in() + g.p("ctrl *gomock.Controller") + g.p("recorder *%vMockRecorder", mockType) + g.out() + g.p("}") + g.p("") + + g.p("// %vMockRecorder is the mock recorder for %v.", mockType, mockType) + g.p("type %vMockRecorder struct {", mockType) + g.in() + g.p("mock *%v", mockType) + g.out() + g.p("}") + g.p("") + + g.p("// New%v creates a new mock instance.", mockType) + g.p("func New%v(ctrl *gomock.Controller) *%v {", mockType, mockType) + g.in() + g.p("mock := &%v{ctrl: ctrl}", mockType) + g.p("mock.recorder = &%vMockRecorder{mock}", mockType) + g.p("return mock") + g.out() + g.p("}") + g.p("") + + // XXX: possible name collision here if someone has EXPECT in their interface. + g.p("// EXPECT returns an object that allows the caller to indicate expected use.") + g.p("func (m *%v) EXPECT() *%vMockRecorder {", mockType, mockType) + g.in() + g.p("return m.recorder") + g.out() + g.p("}") + + g.GenerateMockMethods(mockType, intf, outputPackagePath) + + return nil +} + +type byMethodName []*model.Method + +func (b byMethodName) Len() int { return len(b) } +func (b byMethodName) Swap(i, j int) { b[i], b[j] = b[j], b[i] } +func (b byMethodName) Less(i, j int) bool { return b[i].Name < b[j].Name } + +func (g *generator) GenerateMockMethods(mockType string, intf *model.Interface, pkgOverride string) { + sort.Sort(byMethodName(intf.Methods)) + for _, m := range intf.Methods { + g.p("") + _ = g.GenerateMockMethod(mockType, m, pkgOverride) + g.p("") + _ = g.GenerateMockRecorderMethod(mockType, m) + } +} + +func makeArgString(argNames, argTypes []string) string { + args := make([]string, len(argNames)) + for i, name := range argNames { + // specify the type only once for consecutive args of the same type + if i+1 < len(argTypes) && argTypes[i] == argTypes[i+1] { + args[i] = name + } else { + args[i] = name + " " + argTypes[i] + } + } + return strings.Join(args, ", ") +} + +// GenerateMockMethod generates a mock method implementation. +// If non-empty, pkgOverride is the package in which unqualified types reside. +func (g *generator) GenerateMockMethod(mockType string, m *model.Method, pkgOverride string) error { + argNames := g.getArgNames(m) + argTypes := g.getArgTypes(m, pkgOverride) + argString := makeArgString(argNames, argTypes) + + rets := make([]string, len(m.Out)) + for i, p := range m.Out { + rets[i] = p.Type.String(g.packageMap, pkgOverride) + } + retString := strings.Join(rets, ", ") + if len(rets) > 1 { + retString = "(" + retString + ")" + } + if retString != "" { + retString = " " + retString + } + + ia := newIdentifierAllocator(argNames) + idRecv := ia.allocateIdentifier("m") + + g.p("// %v mocks base method.", m.Name) + g.p("func (%v *%v) %v(%v)%v {", idRecv, mockType, m.Name, argString, retString) + g.in() + g.p("%s.ctrl.T.Helper()", idRecv) + + var callArgs string + if m.Variadic == nil { + if len(argNames) > 0 { + callArgs = ", " + strings.Join(argNames, ", ") + } + } else { + // Non-trivial. The generated code must build a []interface{}, + // but the variadic argument may be any type. + idVarArgs := ia.allocateIdentifier("varargs") + idVArg := ia.allocateIdentifier("a") + g.p("%s := []interface{}{%s}", idVarArgs, strings.Join(argNames[:len(argNames)-1], ", ")) + g.p("for _, %s := range %s {", idVArg, argNames[len(argNames)-1]) + g.in() + g.p("%s = append(%s, %s)", idVarArgs, idVarArgs, idVArg) + g.out() + g.p("}") + callArgs = ", " + idVarArgs + "..." + } + if len(m.Out) == 0 { + g.p(`%v.ctrl.Call(%v, %q%v)`, idRecv, idRecv, m.Name, callArgs) + } else { + idRet := ia.allocateIdentifier("ret") + g.p(`%v := %v.ctrl.Call(%v, %q%v)`, idRet, idRecv, idRecv, m.Name, callArgs) + + // Go does not allow "naked" type assertions on nil values, so we use the two-value form here. + // The value of that is either (x.(T), true) or (Z, false), where Z is the zero value for T. + // Happily, this coincides with the semantics we want here. + retNames := make([]string, len(rets)) + for i, t := range rets { + retNames[i] = ia.allocateIdentifier(fmt.Sprintf("ret%d", i)) + g.p("%s, _ := %s[%d].(%s)", retNames[i], idRet, i, t) + } + g.p("return " + strings.Join(retNames, ", ")) + } + + g.out() + g.p("}") + return nil +} + +func (g *generator) GenerateMockRecorderMethod(mockType string, m *model.Method) error { + argNames := g.getArgNames(m) + + var argString string + if m.Variadic == nil { + argString = strings.Join(argNames, ", ") + } else { + argString = strings.Join(argNames[:len(argNames)-1], ", ") + } + if argString != "" { + argString += " interface{}" + } + + if m.Variadic != nil { + if argString != "" { + argString += ", " + } + argString += fmt.Sprintf("%s ...interface{}", argNames[len(argNames)-1]) + } + + ia := newIdentifierAllocator(argNames) + idRecv := ia.allocateIdentifier("mr") + + g.p("// %v indicates an expected call of %v.", m.Name, m.Name) + g.p("func (%s *%vMockRecorder) %v(%v) *gomock.Call {", idRecv, mockType, m.Name, argString) + g.in() + g.p("%s.mock.ctrl.T.Helper()", idRecv) + + var callArgs string + if m.Variadic == nil { + if len(argNames) > 0 { + callArgs = ", " + strings.Join(argNames, ", ") + } + } else { + if len(argNames) == 1 { + // Easy: just use ... to push the arguments through. + callArgs = ", " + argNames[0] + "..." + } else { + // Hard: create a temporary slice. + idVarArgs := ia.allocateIdentifier("varargs") + g.p("%s := append([]interface{}{%s}, %s...)", + idVarArgs, + strings.Join(argNames[:len(argNames)-1], ", "), + argNames[len(argNames)-1]) + callArgs = ", " + idVarArgs + "..." + } + } + g.p(`return %s.mock.ctrl.RecordCallWithMethodType(%s.mock, "%s", reflect.TypeOf((*%s)(nil).%s)%s)`, idRecv, idRecv, m.Name, mockType, m.Name, callArgs) + + g.out() + g.p("}") + return nil +} + +func (g *generator) getArgNames(m *model.Method) []string { + argNames := make([]string, len(m.In)) + for i, p := range m.In { + name := p.Name + if name == "" || name == "_" { + name = fmt.Sprintf("arg%d", i) + } + argNames[i] = name + } + if m.Variadic != nil { + name := m.Variadic.Name + if name == "" { + name = fmt.Sprintf("arg%d", len(m.In)) + } + argNames = append(argNames, name) + } + return argNames +} + +func (g *generator) getArgTypes(m *model.Method, pkgOverride string) []string { + argTypes := make([]string, len(m.In)) + for i, p := range m.In { + argTypes[i] = p.Type.String(g.packageMap, pkgOverride) + } + if m.Variadic != nil { + argTypes = append(argTypes, "..."+m.Variadic.Type.String(g.packageMap, pkgOverride)) + } + return argTypes +} + +type identifierAllocator map[string]struct{} + +func newIdentifierAllocator(taken []string) identifierAllocator { + a := make(identifierAllocator, len(taken)) + for _, s := range taken { + a[s] = struct{}{} + } + return a +} + +func (o identifierAllocator) allocateIdentifier(want string) string { + id := want + for i := 2; ; i++ { + if _, ok := o[id]; !ok { + o[id] = struct{}{} + return id + } + id = want + "_" + strconv.Itoa(i) + } +} + +// Output returns the generator's output, formatted in the standard Go style. +func (g *generator) Output() []byte { + src, err := toolsimports.Process(g.destination, g.buf.Bytes(), nil) + if err != nil { + log.Fatalf("Failed to format generated source code: %s\n%s", err, g.buf.String()) + } + return src +} + +// createPackageMap returns a map of import path to package name +// for specified importPaths. +func createPackageMap(importPaths []string) map[string]string { + var pkg struct { + Name string + ImportPath string + } + pkgMap := make(map[string]string) + b := bytes.NewBuffer(nil) + args := []string{"list", "-json"} + args = append(args, importPaths...) + cmd := exec.Command("go", args...) + cmd.Stdout = b + cmd.Run() + dec := json.NewDecoder(b) + for dec.More() { + err := dec.Decode(&pkg) + if err != nil { + log.Printf("failed to decode 'go list' output: %v", err) + continue + } + pkgMap[pkg.ImportPath] = pkg.Name + } + return pkgMap +} + +func printVersion() { + if version != "" { + fmt.Printf("v%s\nCommit: %s\nDate: %s\n", version, commit, date) + } else { + printModuleVersion() + } +} + +// parseImportPackage get package import path via source file +// an alternative implementation is to use: +// cfg := &packages.Config{Mode: packages.NeedName, Tests: true, Dir: srcDir} +// pkgs, err := packages.Load(cfg, "file="+source) +// However, it will call "go list" and slow down the performance +func parsePackageImport(srcDir string) (string, error) { + moduleMode := os.Getenv("GO111MODULE") + // trying to find the module + if moduleMode != "off" { + currentDir := srcDir + for { + dat, err := ioutil.ReadFile(filepath.Join(currentDir, "go.mod")) + if os.IsNotExist(err) { + if currentDir == filepath.Dir(currentDir) { + // at the root + break + } + currentDir = filepath.Dir(currentDir) + continue + } else if err != nil { + return "", err + } + modulePath := modfile.ModulePath(dat) + return filepath.ToSlash(filepath.Join(modulePath, strings.TrimPrefix(srcDir, currentDir))), nil + } + } + // fall back to GOPATH mode + goPaths := os.Getenv("GOPATH") + if goPaths == "" { + return "", fmt.Errorf("GOPATH is not set") + } + goPathList := strings.Split(goPaths, string(os.PathListSeparator)) + for _, goPath := range goPathList { + sourceRoot := filepath.Join(goPath, "src") + string(os.PathSeparator) + if strings.HasPrefix(srcDir, sourceRoot) { + return filepath.ToSlash(strings.TrimPrefix(srcDir, sourceRoot)), nil + } + } + return "", errOutsideGoPath +} diff --git a/vendor/github.com/golang/mock/mockgen/model/model.go b/vendor/github.com/golang/mock/mockgen/model/model.go new file mode 100644 index 000000000..2c6a62ceb --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/model/model.go @@ -0,0 +1,495 @@ +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package model contains the data model necessary for generating mock implementations. +package model + +import ( + "encoding/gob" + "fmt" + "io" + "reflect" + "strings" +) + +// pkgPath is the importable path for package model +const pkgPath = "github.com/golang/mock/mockgen/model" + +// Package is a Go package. It may be a subset. +type Package struct { + Name string + PkgPath string + Interfaces []*Interface + DotImports []string +} + +// Print writes the package name and its exported interfaces. +func (pkg *Package) Print(w io.Writer) { + _, _ = fmt.Fprintf(w, "package %s\n", pkg.Name) + for _, intf := range pkg.Interfaces { + intf.Print(w) + } +} + +// Imports returns the imports needed by the Package as a set of import paths. +func (pkg *Package) Imports() map[string]bool { + im := make(map[string]bool) + for _, intf := range pkg.Interfaces { + intf.addImports(im) + } + return im +} + +// Interface is a Go interface. +type Interface struct { + Name string + Methods []*Method +} + +// Print writes the interface name and its methods. +func (intf *Interface) Print(w io.Writer) { + _, _ = fmt.Fprintf(w, "interface %s\n", intf.Name) + for _, m := range intf.Methods { + m.Print(w) + } +} + +func (intf *Interface) addImports(im map[string]bool) { + for _, m := range intf.Methods { + m.addImports(im) + } +} + +// AddMethod adds a new method, de-duplicating by method name. +func (intf *Interface) AddMethod(m *Method) { + for _, me := range intf.Methods { + if me.Name == m.Name { + return + } + } + intf.Methods = append(intf.Methods, m) +} + +// Method is a single method of an interface. +type Method struct { + Name string + In, Out []*Parameter + Variadic *Parameter // may be nil +} + +// Print writes the method name and its signature. +func (m *Method) Print(w io.Writer) { + _, _ = fmt.Fprintf(w, " - method %s\n", m.Name) + if len(m.In) > 0 { + _, _ = fmt.Fprintf(w, " in:\n") + for _, p := range m.In { + p.Print(w) + } + } + if m.Variadic != nil { + _, _ = fmt.Fprintf(w, " ...:\n") + m.Variadic.Print(w) + } + if len(m.Out) > 0 { + _, _ = fmt.Fprintf(w, " out:\n") + for _, p := range m.Out { + p.Print(w) + } + } +} + +func (m *Method) addImports(im map[string]bool) { + for _, p := range m.In { + p.Type.addImports(im) + } + if m.Variadic != nil { + m.Variadic.Type.addImports(im) + } + for _, p := range m.Out { + p.Type.addImports(im) + } +} + +// Parameter is an argument or return parameter of a method. +type Parameter struct { + Name string // may be empty + Type Type +} + +// Print writes a method parameter. +func (p *Parameter) Print(w io.Writer) { + n := p.Name + if n == "" { + n = `""` + } + _, _ = fmt.Fprintf(w, " - %v: %v\n", n, p.Type.String(nil, "")) +} + +// Type is a Go type. +type Type interface { + String(pm map[string]string, pkgOverride string) string + addImports(im map[string]bool) +} + +func init() { + gob.Register(&ArrayType{}) + gob.Register(&ChanType{}) + gob.Register(&FuncType{}) + gob.Register(&MapType{}) + gob.Register(&NamedType{}) + gob.Register(&PointerType{}) + + // Call gob.RegisterName to make sure it has the consistent name registered + // for both gob decoder and encoder. + // + // For a non-pointer type, gob.Register will try to get package full path by + // calling rt.PkgPath() for a name to register. If your project has vendor + // directory, it is possible that PkgPath will get a path like this: + // ../../../vendor/github.com/golang/mock/mockgen/model + gob.RegisterName(pkgPath+".PredeclaredType", PredeclaredType("")) +} + +// ArrayType is an array or slice type. +type ArrayType struct { + Len int // -1 for slices, >= 0 for arrays + Type Type +} + +func (at *ArrayType) String(pm map[string]string, pkgOverride string) string { + s := "[]" + if at.Len > -1 { + s = fmt.Sprintf("[%d]", at.Len) + } + return s + at.Type.String(pm, pkgOverride) +} + +func (at *ArrayType) addImports(im map[string]bool) { at.Type.addImports(im) } + +// ChanType is a channel type. +type ChanType struct { + Dir ChanDir // 0, 1 or 2 + Type Type +} + +func (ct *ChanType) String(pm map[string]string, pkgOverride string) string { + s := ct.Type.String(pm, pkgOverride) + if ct.Dir == RecvDir { + return "<-chan " + s + } + if ct.Dir == SendDir { + return "chan<- " + s + } + return "chan " + s +} + +func (ct *ChanType) addImports(im map[string]bool) { ct.Type.addImports(im) } + +// ChanDir is a channel direction. +type ChanDir int + +// Constants for channel directions. +const ( + RecvDir ChanDir = 1 + SendDir ChanDir = 2 +) + +// FuncType is a function type. +type FuncType struct { + In, Out []*Parameter + Variadic *Parameter // may be nil +} + +func (ft *FuncType) String(pm map[string]string, pkgOverride string) string { + args := make([]string, len(ft.In)) + for i, p := range ft.In { + args[i] = p.Type.String(pm, pkgOverride) + } + if ft.Variadic != nil { + args = append(args, "..."+ft.Variadic.Type.String(pm, pkgOverride)) + } + rets := make([]string, len(ft.Out)) + for i, p := range ft.Out { + rets[i] = p.Type.String(pm, pkgOverride) + } + retString := strings.Join(rets, ", ") + if nOut := len(ft.Out); nOut == 1 { + retString = " " + retString + } else if nOut > 1 { + retString = " (" + retString + ")" + } + return "func(" + strings.Join(args, ", ") + ")" + retString +} + +func (ft *FuncType) addImports(im map[string]bool) { + for _, p := range ft.In { + p.Type.addImports(im) + } + if ft.Variadic != nil { + ft.Variadic.Type.addImports(im) + } + for _, p := range ft.Out { + p.Type.addImports(im) + } +} + +// MapType is a map type. +type MapType struct { + Key, Value Type +} + +func (mt *MapType) String(pm map[string]string, pkgOverride string) string { + return "map[" + mt.Key.String(pm, pkgOverride) + "]" + mt.Value.String(pm, pkgOverride) +} + +func (mt *MapType) addImports(im map[string]bool) { + mt.Key.addImports(im) + mt.Value.addImports(im) +} + +// NamedType is an exported type in a package. +type NamedType struct { + Package string // may be empty + Type string +} + +func (nt *NamedType) String(pm map[string]string, pkgOverride string) string { + if pkgOverride == nt.Package { + return nt.Type + } + prefix := pm[nt.Package] + if prefix != "" { + return prefix + "." + nt.Type + } + + return nt.Type +} + +func (nt *NamedType) addImports(im map[string]bool) { + if nt.Package != "" { + im[nt.Package] = true + } +} + +// PointerType is a pointer to another type. +type PointerType struct { + Type Type +} + +func (pt *PointerType) String(pm map[string]string, pkgOverride string) string { + return "*" + pt.Type.String(pm, pkgOverride) +} +func (pt *PointerType) addImports(im map[string]bool) { pt.Type.addImports(im) } + +// PredeclaredType is a predeclared type such as "int". +type PredeclaredType string + +func (pt PredeclaredType) String(map[string]string, string) string { return string(pt) } +func (pt PredeclaredType) addImports(map[string]bool) {} + +// The following code is intended to be called by the program generated by ../reflect.go. + +// InterfaceFromInterfaceType returns a pointer to an interface for the +// given reflection interface type. +func InterfaceFromInterfaceType(it reflect.Type) (*Interface, error) { + if it.Kind() != reflect.Interface { + return nil, fmt.Errorf("%v is not an interface", it) + } + intf := &Interface{} + + for i := 0; i < it.NumMethod(); i++ { + mt := it.Method(i) + // TODO: need to skip unexported methods? or just raise an error? + m := &Method{ + Name: mt.Name, + } + + var err error + m.In, m.Variadic, m.Out, err = funcArgsFromType(mt.Type) + if err != nil { + return nil, err + } + + intf.AddMethod(m) + } + + return intf, nil +} + +// t's Kind must be a reflect.Func. +func funcArgsFromType(t reflect.Type) (in []*Parameter, variadic *Parameter, out []*Parameter, err error) { + nin := t.NumIn() + if t.IsVariadic() { + nin-- + } + var p *Parameter + for i := 0; i < nin; i++ { + p, err = parameterFromType(t.In(i)) + if err != nil { + return + } + in = append(in, p) + } + if t.IsVariadic() { + p, err = parameterFromType(t.In(nin).Elem()) + if err != nil { + return + } + variadic = p + } + for i := 0; i < t.NumOut(); i++ { + p, err = parameterFromType(t.Out(i)) + if err != nil { + return + } + out = append(out, p) + } + return +} + +func parameterFromType(t reflect.Type) (*Parameter, error) { + tt, err := typeFromType(t) + if err != nil { + return nil, err + } + return &Parameter{Type: tt}, nil +} + +var errorType = reflect.TypeOf((*error)(nil)).Elem() + +var byteType = reflect.TypeOf(byte(0)) + +func typeFromType(t reflect.Type) (Type, error) { + // Hack workaround for https://golang.org/issue/3853. + // This explicit check should not be necessary. + if t == byteType { + return PredeclaredType("byte"), nil + } + + if imp := t.PkgPath(); imp != "" { + return &NamedType{ + Package: impPath(imp), + Type: t.Name(), + }, nil + } + + // only unnamed or predeclared types after here + + // Lots of types have element types. Let's do the parsing and error checking for all of them. + var elemType Type + switch t.Kind() { + case reflect.Array, reflect.Chan, reflect.Map, reflect.Ptr, reflect.Slice: + var err error + elemType, err = typeFromType(t.Elem()) + if err != nil { + return nil, err + } + } + + switch t.Kind() { + case reflect.Array: + return &ArrayType{ + Len: t.Len(), + Type: elemType, + }, nil + case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, + reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String: + return PredeclaredType(t.Kind().String()), nil + case reflect.Chan: + var dir ChanDir + switch t.ChanDir() { + case reflect.RecvDir: + dir = RecvDir + case reflect.SendDir: + dir = SendDir + } + return &ChanType{ + Dir: dir, + Type: elemType, + }, nil + case reflect.Func: + in, variadic, out, err := funcArgsFromType(t) + if err != nil { + return nil, err + } + return &FuncType{ + In: in, + Out: out, + Variadic: variadic, + }, nil + case reflect.Interface: + // Two special interfaces. + if t.NumMethod() == 0 { + return PredeclaredType("interface{}"), nil + } + if t == errorType { + return PredeclaredType("error"), nil + } + case reflect.Map: + kt, err := typeFromType(t.Key()) + if err != nil { + return nil, err + } + return &MapType{ + Key: kt, + Value: elemType, + }, nil + case reflect.Ptr: + return &PointerType{ + Type: elemType, + }, nil + case reflect.Slice: + return &ArrayType{ + Len: -1, + Type: elemType, + }, nil + case reflect.Struct: + if t.NumField() == 0 { + return PredeclaredType("struct{}"), nil + } + } + + // TODO: Struct, UnsafePointer + return nil, fmt.Errorf("can't yet turn %v (%v) into a model.Type", t, t.Kind()) +} + +// impPath sanitizes the package path returned by `PkgPath` method of a reflect Type so that +// it is importable. PkgPath might return a path that includes "vendor". These paths do not +// compile, so we need to remove everything up to and including "/vendor/". +// See https://github.com/golang/go/issues/12019. +func impPath(imp string) string { + if strings.HasPrefix(imp, "vendor/") { + imp = "/" + imp + } + if i := strings.LastIndex(imp, "/vendor/"); i != -1 { + imp = imp[i+len("/vendor/"):] + } + return imp +} + +// ErrorInterface represent built-in error interface. +var ErrorInterface = Interface{ + Name: "error", + Methods: []*Method{ + { + Name: "Error", + Out: []*Parameter{ + { + Name: "", + Type: PredeclaredType("string"), + }, + }, + }, + }, +} diff --git a/vendor/github.com/golang/mock/mockgen/parse.go b/vendor/github.com/golang/mock/mockgen/parse.go new file mode 100644 index 000000000..bf6902cd5 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/parse.go @@ -0,0 +1,644 @@ +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +// This file contains the model construction by parsing source files. + +import ( + "errors" + "flag" + "fmt" + "go/ast" + "go/build" + "go/importer" + "go/parser" + "go/token" + "go/types" + "io/ioutil" + "log" + "path" + "path/filepath" + "strconv" + "strings" + + "github.com/golang/mock/mockgen/model" +) + +var ( + imports = flag.String("imports", "", "(source mode) Comma-separated name=path pairs of explicit imports to use.") + auxFiles = flag.String("aux_files", "", "(source mode) Comma-separated pkg=path pairs of auxiliary Go source files.") +) + +// sourceMode generates mocks via source file. +func sourceMode(source string) (*model.Package, error) { + srcDir, err := filepath.Abs(filepath.Dir(source)) + if err != nil { + return nil, fmt.Errorf("failed getting source directory: %v", err) + } + + packageImport, err := parsePackageImport(srcDir) + if err != nil { + return nil, err + } + + fs := token.NewFileSet() + file, err := parser.ParseFile(fs, source, nil, 0) + if err != nil { + return nil, fmt.Errorf("failed parsing source file %v: %v", source, err) + } + + p := &fileParser{ + fileSet: fs, + imports: make(map[string]importedPackage), + importedInterfaces: make(map[string]map[string]*ast.InterfaceType), + auxInterfaces: make(map[string]map[string]*ast.InterfaceType), + srcDir: srcDir, + } + + // Handle -imports. + dotImports := make(map[string]bool) + if *imports != "" { + for _, kv := range strings.Split(*imports, ",") { + eq := strings.Index(kv, "=") + k, v := kv[:eq], kv[eq+1:] + if k == "." { + dotImports[v] = true + } else { + p.imports[k] = importedPkg{path: v} + } + } + } + + // Handle -aux_files. + if err := p.parseAuxFiles(*auxFiles); err != nil { + return nil, err + } + p.addAuxInterfacesFromFile(packageImport, file) // this file + + pkg, err := p.parseFile(packageImport, file) + if err != nil { + return nil, err + } + for pkgPath := range dotImports { + pkg.DotImports = append(pkg.DotImports, pkgPath) + } + return pkg, nil +} + +type importedPackage interface { + Path() string + Parser() *fileParser +} + +type importedPkg struct { + path string + parser *fileParser +} + +func (i importedPkg) Path() string { return i.path } +func (i importedPkg) Parser() *fileParser { return i.parser } + +// duplicateImport is a bit of a misnomer. Currently the parser can't +// handle cases of multi-file packages importing different packages +// under the same name. Often these imports would not be problematic, +// so this type lets us defer raising an error unless the package name +// is actually used. +type duplicateImport struct { + name string + duplicates []string +} + +func (d duplicateImport) Error() string { + return fmt.Sprintf("%q is ambiguous because of duplicate imports: %v", d.name, d.duplicates) +} + +func (d duplicateImport) Path() string { log.Fatal(d.Error()); return "" } +func (d duplicateImport) Parser() *fileParser { log.Fatal(d.Error()); return nil } + +type fileParser struct { + fileSet *token.FileSet + imports map[string]importedPackage // package name => imported package + importedInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface + + auxFiles []*ast.File + auxInterfaces map[string]map[string]*ast.InterfaceType // package (or "") => name => interface + + srcDir string +} + +func (p *fileParser) errorf(pos token.Pos, format string, args ...interface{}) error { + ps := p.fileSet.Position(pos) + format = "%s:%d:%d: " + format + args = append([]interface{}{ps.Filename, ps.Line, ps.Column}, args...) + return fmt.Errorf(format, args...) +} + +func (p *fileParser) parseAuxFiles(auxFiles string) error { + auxFiles = strings.TrimSpace(auxFiles) + if auxFiles == "" { + return nil + } + for _, kv := range strings.Split(auxFiles, ",") { + parts := strings.SplitN(kv, "=", 2) + if len(parts) != 2 { + return fmt.Errorf("bad aux file spec: %v", kv) + } + pkg, fpath := parts[0], parts[1] + + file, err := parser.ParseFile(p.fileSet, fpath, nil, 0) + if err != nil { + return err + } + p.auxFiles = append(p.auxFiles, file) + p.addAuxInterfacesFromFile(pkg, file) + } + return nil +} + +func (p *fileParser) addAuxInterfacesFromFile(pkg string, file *ast.File) { + if _, ok := p.auxInterfaces[pkg]; !ok { + p.auxInterfaces[pkg] = make(map[string]*ast.InterfaceType) + } + for ni := range iterInterfaces(file) { + p.auxInterfaces[pkg][ni.name.Name] = ni.it + } +} + +// parseFile loads all file imports and auxiliary files import into the +// fileParser, parses all file interfaces and returns package model. +func (p *fileParser) parseFile(importPath string, file *ast.File) (*model.Package, error) { + allImports, dotImports := importsOfFile(file) + // Don't stomp imports provided by -imports. Those should take precedence. + for pkg, pkgI := range allImports { + if _, ok := p.imports[pkg]; !ok { + p.imports[pkg] = pkgI + } + } + // Add imports from auxiliary files, which might be needed for embedded interfaces. + // Don't stomp any other imports. + for _, f := range p.auxFiles { + auxImports, _ := importsOfFile(f) + for pkg, pkgI := range auxImports { + if _, ok := p.imports[pkg]; !ok { + p.imports[pkg] = pkgI + } + } + } + + var is []*model.Interface + for ni := range iterInterfaces(file) { + i, err := p.parseInterface(ni.name.String(), importPath, ni.it) + if err != nil { + return nil, err + } + is = append(is, i) + } + return &model.Package{ + Name: file.Name.String(), + PkgPath: importPath, + Interfaces: is, + DotImports: dotImports, + }, nil +} + +// parsePackage loads package specified by path, parses it and returns +// a new fileParser with the parsed imports and interfaces. +func (p *fileParser) parsePackage(path string) (*fileParser, error) { + newP := &fileParser{ + fileSet: token.NewFileSet(), + imports: make(map[string]importedPackage), + importedInterfaces: make(map[string]map[string]*ast.InterfaceType), + auxInterfaces: make(map[string]map[string]*ast.InterfaceType), + srcDir: p.srcDir, + } + + var pkgs map[string]*ast.Package + if imp, err := build.Import(path, newP.srcDir, build.FindOnly); err != nil { + return nil, err + } else if pkgs, err = parser.ParseDir(newP.fileSet, imp.Dir, nil, 0); err != nil { + return nil, err + } + + for _, pkg := range pkgs { + file := ast.MergePackageFiles(pkg, ast.FilterFuncDuplicates|ast.FilterUnassociatedComments|ast.FilterImportDuplicates) + if _, ok := newP.importedInterfaces[path]; !ok { + newP.importedInterfaces[path] = make(map[string]*ast.InterfaceType) + } + for ni := range iterInterfaces(file) { + newP.importedInterfaces[path][ni.name.Name] = ni.it + } + imports, _ := importsOfFile(file) + for pkgName, pkgI := range imports { + newP.imports[pkgName] = pkgI + } + } + return newP, nil +} + +func (p *fileParser) parseInterface(name, pkg string, it *ast.InterfaceType) (*model.Interface, error) { + iface := &model.Interface{Name: name} + for _, field := range it.Methods.List { + switch v := field.Type.(type) { + case *ast.FuncType: + if nn := len(field.Names); nn != 1 { + return nil, fmt.Errorf("expected one name for interface %v, got %d", iface.Name, nn) + } + m := &model.Method{ + Name: field.Names[0].String(), + } + var err error + m.In, m.Variadic, m.Out, err = p.parseFunc(pkg, v) + if err != nil { + return nil, err + } + iface.AddMethod(m) + case *ast.Ident: + // Embedded interface in this package. + embeddedIfaceType := p.auxInterfaces[pkg][v.String()] + if embeddedIfaceType == nil { + embeddedIfaceType = p.importedInterfaces[pkg][v.String()] + } + + var embeddedIface *model.Interface + if embeddedIfaceType != nil { + var err error + embeddedIface, err = p.parseInterface(v.String(), pkg, embeddedIfaceType) + if err != nil { + return nil, err + } + } else { + // This is built-in error interface. + if v.String() == model.ErrorInterface.Name { + embeddedIface = &model.ErrorInterface + } else { + return nil, p.errorf(v.Pos(), "unknown embedded interface %s", v.String()) + } + } + // Copy the methods. + for _, m := range embeddedIface.Methods { + iface.AddMethod(m) + } + case *ast.SelectorExpr: + // Embedded interface in another package. + filePkg, sel := v.X.(*ast.Ident).String(), v.Sel.String() + embeddedPkg, ok := p.imports[filePkg] + if !ok { + return nil, p.errorf(v.X.Pos(), "unknown package %s", filePkg) + } + + var embeddedIface *model.Interface + var err error + embeddedIfaceType := p.auxInterfaces[filePkg][sel] + if embeddedIfaceType != nil { + embeddedIface, err = p.parseInterface(sel, filePkg, embeddedIfaceType) + if err != nil { + return nil, err + } + } else { + path := embeddedPkg.Path() + parser := embeddedPkg.Parser() + if parser == nil { + ip, err := p.parsePackage(path) + if err != nil { + return nil, p.errorf(v.Pos(), "could not parse package %s: %v", path, err) + } + parser = ip + p.imports[filePkg] = importedPkg{ + path: embeddedPkg.Path(), + parser: parser, + } + } + if embeddedIfaceType = parser.importedInterfaces[path][sel]; embeddedIfaceType == nil { + return nil, p.errorf(v.Pos(), "unknown embedded interface %s.%s", path, sel) + } + embeddedIface, err = parser.parseInterface(sel, path, embeddedIfaceType) + if err != nil { + return nil, err + } + } + // Copy the methods. + // TODO: apply shadowing rules. + for _, m := range embeddedIface.Methods { + iface.AddMethod(m) + } + default: + return nil, fmt.Errorf("don't know how to mock method of type %T", field.Type) + } + } + return iface, nil +} + +func (p *fileParser) parseFunc(pkg string, f *ast.FuncType) (inParam []*model.Parameter, variadic *model.Parameter, outParam []*model.Parameter, err error) { + if f.Params != nil { + regParams := f.Params.List + if isVariadic(f) { + n := len(regParams) + varParams := regParams[n-1:] + regParams = regParams[:n-1] + vp, err := p.parseFieldList(pkg, varParams) + if err != nil { + return nil, nil, nil, p.errorf(varParams[0].Pos(), "failed parsing variadic argument: %v", err) + } + variadic = vp[0] + } + inParam, err = p.parseFieldList(pkg, regParams) + if err != nil { + return nil, nil, nil, p.errorf(f.Pos(), "failed parsing arguments: %v", err) + } + } + if f.Results != nil { + outParam, err = p.parseFieldList(pkg, f.Results.List) + if err != nil { + return nil, nil, nil, p.errorf(f.Pos(), "failed parsing returns: %v", err) + } + } + return +} + +func (p *fileParser) parseFieldList(pkg string, fields []*ast.Field) ([]*model.Parameter, error) { + nf := 0 + for _, f := range fields { + nn := len(f.Names) + if nn == 0 { + nn = 1 // anonymous parameter + } + nf += nn + } + if nf == 0 { + return nil, nil + } + ps := make([]*model.Parameter, nf) + i := 0 // destination index + for _, f := range fields { + t, err := p.parseType(pkg, f.Type) + if err != nil { + return nil, err + } + + if len(f.Names) == 0 { + // anonymous arg + ps[i] = &model.Parameter{Type: t} + i++ + continue + } + for _, name := range f.Names { + ps[i] = &model.Parameter{Name: name.Name, Type: t} + i++ + } + } + return ps, nil +} + +func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) { + switch v := typ.(type) { + case *ast.ArrayType: + ln := -1 + if v.Len != nil { + var value string + switch val := v.Len.(type) { + case (*ast.BasicLit): + value = val.Value + case (*ast.Ident): + // when the length is a const defined locally + value = val.Obj.Decl.(*ast.ValueSpec).Values[0].(*ast.BasicLit).Value + case (*ast.SelectorExpr): + // when the length is a const defined in an external package + usedPkg, err := importer.Default().Import(fmt.Sprintf("%s", val.X)) + if err != nil { + return nil, p.errorf(v.Len.Pos(), "unknown package in array length: %v", err) + } + ev, err := types.Eval(token.NewFileSet(), usedPkg, token.NoPos, val.Sel.Name) + if err != nil { + return nil, p.errorf(v.Len.Pos(), "unknown constant in array length: %v", err) + } + value = ev.Value.String() + } + + x, err := strconv.Atoi(value) + if err != nil { + return nil, p.errorf(v.Len.Pos(), "bad array size: %v", err) + } + ln = x + } + t, err := p.parseType(pkg, v.Elt) + if err != nil { + return nil, err + } + return &model.ArrayType{Len: ln, Type: t}, nil + case *ast.ChanType: + t, err := p.parseType(pkg, v.Value) + if err != nil { + return nil, err + } + var dir model.ChanDir + if v.Dir == ast.SEND { + dir = model.SendDir + } + if v.Dir == ast.RECV { + dir = model.RecvDir + } + return &model.ChanType{Dir: dir, Type: t}, nil + case *ast.Ellipsis: + // assume we're parsing a variadic argument + return p.parseType(pkg, v.Elt) + case *ast.FuncType: + in, variadic, out, err := p.parseFunc(pkg, v) + if err != nil { + return nil, err + } + return &model.FuncType{In: in, Out: out, Variadic: variadic}, nil + case *ast.Ident: + if v.IsExported() { + // `pkg` may be an aliased imported pkg + // if so, patch the import w/ the fully qualified import + maybeImportedPkg, ok := p.imports[pkg] + if ok { + pkg = maybeImportedPkg.Path() + } + // assume type in this package + return &model.NamedType{Package: pkg, Type: v.Name}, nil + } + + // assume predeclared type + return model.PredeclaredType(v.Name), nil + case *ast.InterfaceType: + if v.Methods != nil && len(v.Methods.List) > 0 { + return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed interface types") + } + return model.PredeclaredType("interface{}"), nil + case *ast.MapType: + key, err := p.parseType(pkg, v.Key) + if err != nil { + return nil, err + } + value, err := p.parseType(pkg, v.Value) + if err != nil { + return nil, err + } + return &model.MapType{Key: key, Value: value}, nil + case *ast.SelectorExpr: + pkgName := v.X.(*ast.Ident).String() + pkg, ok := p.imports[pkgName] + if !ok { + return nil, p.errorf(v.Pos(), "unknown package %q", pkgName) + } + return &model.NamedType{Package: pkg.Path(), Type: v.Sel.String()}, nil + case *ast.StarExpr: + t, err := p.parseType(pkg, v.X) + if err != nil { + return nil, err + } + return &model.PointerType{Type: t}, nil + case *ast.StructType: + if v.Fields != nil && len(v.Fields.List) > 0 { + return nil, p.errorf(v.Pos(), "can't handle non-empty unnamed struct types") + } + return model.PredeclaredType("struct{}"), nil + case *ast.ParenExpr: + return p.parseType(pkg, v.X) + } + + return nil, fmt.Errorf("don't know how to parse type %T", typ) +} + +// importsOfFile returns a map of package name to import path +// of the imports in file. +func importsOfFile(file *ast.File) (normalImports map[string]importedPackage, dotImports []string) { + var importPaths []string + for _, is := range file.Imports { + if is.Name != nil { + continue + } + importPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes + importPaths = append(importPaths, importPath) + } + packagesName := createPackageMap(importPaths) + normalImports = make(map[string]importedPackage) + dotImports = make([]string, 0) + for _, is := range file.Imports { + var pkgName string + importPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes + + if is.Name != nil { + // Named imports are always certain. + if is.Name.Name == "_" { + continue + } + pkgName = is.Name.Name + } else { + pkg, ok := packagesName[importPath] + if !ok { + // Fallback to import path suffix. Note that this is uncertain. + _, last := path.Split(importPath) + // If the last path component has dots, the first dot-delimited + // field is used as the name. + pkgName = strings.SplitN(last, ".", 2)[0] + } else { + pkgName = pkg + } + } + + if pkgName == "." { + dotImports = append(dotImports, importPath) + } else { + if pkg, ok := normalImports[pkgName]; ok { + switch p := pkg.(type) { + case duplicateImport: + normalImports[pkgName] = duplicateImport{ + name: p.name, + duplicates: append([]string{importPath}, p.duplicates...), + } + case importedPkg: + normalImports[pkgName] = duplicateImport{ + name: pkgName, + duplicates: []string{p.path, importPath}, + } + } + } else { + normalImports[pkgName] = importedPkg{path: importPath} + } + } + } + return +} + +type namedInterface struct { + name *ast.Ident + it *ast.InterfaceType +} + +// Create an iterator over all interfaces in file. +func iterInterfaces(file *ast.File) <-chan namedInterface { + ch := make(chan namedInterface) + go func() { + for _, decl := range file.Decls { + gd, ok := decl.(*ast.GenDecl) + if !ok || gd.Tok != token.TYPE { + continue + } + for _, spec := range gd.Specs { + ts, ok := spec.(*ast.TypeSpec) + if !ok { + continue + } + it, ok := ts.Type.(*ast.InterfaceType) + if !ok { + continue + } + + ch <- namedInterface{ts.Name, it} + } + } + close(ch) + }() + return ch +} + +// isVariadic returns whether the function is variadic. +func isVariadic(f *ast.FuncType) bool { + nargs := len(f.Params.List) + if nargs == 0 { + return false + } + _, ok := f.Params.List[nargs-1].Type.(*ast.Ellipsis) + return ok +} + +// packageNameOfDir get package import path via dir +func packageNameOfDir(srcDir string) (string, error) { + files, err := ioutil.ReadDir(srcDir) + if err != nil { + log.Fatal(err) + } + + var goFilePath string + for _, file := range files { + if !file.IsDir() && strings.HasSuffix(file.Name(), ".go") { + goFilePath = file.Name() + break + } + } + if goFilePath == "" { + return "", fmt.Errorf("go source file not found %s", srcDir) + } + + packageImport, err := parsePackageImport(srcDir) + if err != nil { + return "", err + } + return packageImport, nil +} + +var errOutsideGoPath = errors.New("source directory is outside GOPATH") diff --git a/vendor/github.com/golang/mock/mockgen/reflect.go b/vendor/github.com/golang/mock/mockgen/reflect.go new file mode 100644 index 000000000..e24efce0b --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/reflect.go @@ -0,0 +1,256 @@ +// Copyright 2012 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +// This file contains the model construction by reflection. + +import ( + "bytes" + "encoding/gob" + "flag" + "fmt" + "go/build" + "io" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "strings" + "text/template" + + "github.com/golang/mock/mockgen/model" +) + +var ( + progOnly = flag.Bool("prog_only", false, "(reflect mode) Only generate the reflection program; write it to stdout and exit.") + execOnly = flag.String("exec_only", "", "(reflect mode) If set, execute this reflection program.") + buildFlags = flag.String("build_flags", "", "(reflect mode) Additional flags for go build.") +) + +// reflectMode generates mocks via reflection on an interface. +func reflectMode(importPath string, symbols []string) (*model.Package, error) { + if *execOnly != "" { + return run(*execOnly) + } + + program, err := writeProgram(importPath, symbols) + if err != nil { + return nil, err + } + + if *progOnly { + if _, err := os.Stdout.Write(program); err != nil { + return nil, err + } + os.Exit(0) + } + + wd, _ := os.Getwd() + + // Try to run the reflection program in the current working directory. + if p, err := runInDir(program, wd); err == nil { + return p, nil + } + + // Try to run the program in the same directory as the input package. + if p, err := build.Import(importPath, wd, build.FindOnly); err == nil { + dir := p.Dir + if p, err := runInDir(program, dir); err == nil { + return p, nil + } + } + + // Try to run it in a standard temp directory. + return runInDir(program, "") +} + +func writeProgram(importPath string, symbols []string) ([]byte, error) { + var program bytes.Buffer + data := reflectData{ + ImportPath: importPath, + Symbols: symbols, + } + if err := reflectProgram.Execute(&program, &data); err != nil { + return nil, err + } + return program.Bytes(), nil +} + +// run the given program and parse the output as a model.Package. +func run(program string) (*model.Package, error) { + f, err := ioutil.TempFile("", "") + if err != nil { + return nil, err + } + + filename := f.Name() + defer os.Remove(filename) + if err := f.Close(); err != nil { + return nil, err + } + + // Run the program. + cmd := exec.Command(program, "-output", filename) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + return nil, err + } + + f, err = os.Open(filename) + if err != nil { + return nil, err + } + + // Process output. + var pkg model.Package + if err := gob.NewDecoder(f).Decode(&pkg); err != nil { + return nil, err + } + + if err := f.Close(); err != nil { + return nil, err + } + + return &pkg, nil +} + +// runInDir writes the given program into the given dir, runs it there, and +// parses the output as a model.Package. +func runInDir(program []byte, dir string) (*model.Package, error) { + // We use TempDir instead of TempFile so we can control the filename. + tmpDir, err := ioutil.TempDir(dir, "gomock_reflect_") + if err != nil { + return nil, err + } + defer func() { + if err := os.RemoveAll(tmpDir); err != nil { + log.Printf("failed to remove temp directory: %s", err) + } + }() + const progSource = "prog.go" + var progBinary = "prog.bin" + if runtime.GOOS == "windows" { + // Windows won't execute a program unless it has a ".exe" suffix. + progBinary += ".exe" + } + + if err := ioutil.WriteFile(filepath.Join(tmpDir, progSource), program, 0600); err != nil { + return nil, err + } + + cmdArgs := []string{} + cmdArgs = append(cmdArgs, "build") + if *buildFlags != "" { + cmdArgs = append(cmdArgs, strings.Split(*buildFlags, " ")...) + } + cmdArgs = append(cmdArgs, "-o", progBinary, progSource) + + // Build the program. + buf := bytes.NewBuffer(nil) + cmd := exec.Command("go", cmdArgs...) + cmd.Dir = tmpDir + cmd.Stdout = os.Stdout + cmd.Stderr = io.MultiWriter(os.Stderr, buf) + if err := cmd.Run(); err != nil { + sErr := buf.String() + if strings.Contains(sErr, `cannot find package "."`) && + strings.Contains(sErr, "github.com/golang/mock/mockgen/model") { + fmt.Fprint(os.Stderr, "Please reference the steps in the README to fix this error:\n\thttps://github.com/golang/mock#reflect-vendoring-error.") + return nil, err + } + return nil, err + } + + return run(filepath.Join(tmpDir, progBinary)) +} + +type reflectData struct { + ImportPath string + Symbols []string +} + +// This program reflects on an interface value, and prints the +// gob encoding of a model.Package to standard output. +// JSON doesn't work because of the model.Type interface. +var reflectProgram = template.Must(template.New("program").Parse(` +package main + +import ( + "encoding/gob" + "flag" + "fmt" + "os" + "path" + "reflect" + + "github.com/golang/mock/mockgen/model" + + pkg_ {{printf "%q" .ImportPath}} +) + +var output = flag.String("output", "", "The output file name, or empty to use stdout.") + +func main() { + flag.Parse() + + its := []struct{ + sym string + typ reflect.Type + }{ + {{range .Symbols}} + { {{printf "%q" .}}, reflect.TypeOf((*pkg_.{{.}})(nil)).Elem()}, + {{end}} + } + pkg := &model.Package{ + // NOTE: This behaves contrary to documented behaviour if the + // package name is not the final component of the import path. + // The reflect package doesn't expose the package name, though. + Name: path.Base({{printf "%q" .ImportPath}}), + } + + for _, it := range its { + intf, err := model.InterfaceFromInterfaceType(it.typ) + if err != nil { + fmt.Fprintf(os.Stderr, "Reflection: %v\n", err) + os.Exit(1) + } + intf.Name = it.sym + pkg.Interfaces = append(pkg.Interfaces, intf) + } + + outfile := os.Stdout + if len(*output) != 0 { + var err error + outfile, err = os.Create(*output) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to open output file %q", *output) + } + defer func() { + if err := outfile.Close(); err != nil { + fmt.Fprintf(os.Stderr, "failed to close output file %q", *output) + os.Exit(1) + } + }() + } + + if err := gob.NewEncoder(outfile).Encode(pkg); err != nil { + fmt.Fprintf(os.Stderr, "gob encode: %v\n", err) + os.Exit(1) + } +} +`)) diff --git a/vendor/github.com/golang/mock/mockgen/version.1.11.go b/vendor/github.com/golang/mock/mockgen/version.1.11.go new file mode 100644 index 000000000..e6b25db23 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/version.1.11.go @@ -0,0 +1,26 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !go1.12 + +package main + +import ( + "log" +) + +func printModuleVersion() { + log.Printf("No version information is available for Mockgen compiled with " + + "version 1.11") +} diff --git a/vendor/github.com/golang/mock/mockgen/version.1.12.go b/vendor/github.com/golang/mock/mockgen/version.1.12.go new file mode 100644 index 000000000..ad121ae63 --- /dev/null +++ b/vendor/github.com/golang/mock/mockgen/version.1.12.go @@ -0,0 +1,35 @@ +// Copyright 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// +build go1.12 + +package main + +import ( + "fmt" + "log" + "runtime/debug" +) + +func printModuleVersion() { + if bi, exists := debug.ReadBuildInfo(); exists { + fmt.Println(bi.Main.Version) + } else { + log.Printf("No version information found. Make sure to use " + + "GO111MODULE=on when running 'go get' in order to use specific " + + "version of the binary.") + } + +} diff --git a/vendor/github.com/ipfs/go-cid/cid.go b/vendor/github.com/ipfs/go-cid/cid.go index bc5704aa2..651c94dfa 100644 --- a/vendor/github.com/ipfs/go-cid/cid.go +++ b/vendor/github.com/ipfs/go-cid/cid.go @@ -10,7 +10,7 @@ // // A CIDv1 has four parts: // -// ::= +// ::= // // As shown above, the CID implementation relies heavily on Multiformats, // particularly Multibase @@ -181,10 +181,19 @@ func Parse(v interface{}) (Cid, error) { } } +// MustParse calls Parse but will panic on error. +func MustParse(v interface{}) Cid { + c, err := Parse(v) + if err != nil { + panic(err) + } + return c +} + // Decode parses a Cid-encoded string and returns a Cid object. // For CidV1, a Cid-encoded string is primarily a multibase string: // -// +// // // The base-encoded string represents a: // @@ -240,7 +249,7 @@ func ExtractEncoding(v string) (mbase.Encoding, error) { // Cast takes a Cid data slice, parses it and returns a Cid. // For CidV1, the data buffer is in the form: // -// +// // // CidV0 are also supported. In particular, data buffers starting // with length 34 bytes, which starts with bytes [18,32...] are considered @@ -369,7 +378,13 @@ func (c Cid) Hash() mh.Multihash { // Bytes returns the byte representation of a Cid. // The output of bytes can be parsed back into a Cid // with Cast(). +// +// If c.Defined() == false, it return a nil slice and may not +// be parsable with Cast(). func (c Cid) Bytes() []byte { + if !c.Defined() { + return nil + } return []byte(c.str) } @@ -450,7 +465,7 @@ func (c *Cid) UnmarshalJSON(b []byte) error { // MarshalJSON procudes a JSON representation of a Cid, which looks as follows: // -// { "/": "" } +// { "/": "" } // // Note that this formatting comes from the IPLD specification // (https://github.com/ipld/specs/tree/master/ipld) @@ -507,7 +522,8 @@ func (c Cid) Prefix() Prefix { // and the Multihash length. It does not contains // any actual content information. // NOTE: The use -1 in MhLength to mean default length is deprecated, -// use the V0Builder or V1Builder structures instead +// +// use the V0Builder or V1Builder structures instead type Prefix struct { Version uint64 Codec uint64 @@ -546,7 +562,7 @@ func (p Prefix) Sum(data []byte) (Cid, error) { // Bytes returns a byte representation of a Prefix. It looks like: // -// +// func (p Prefix) Bytes() []byte { size := varint.UvarintSize(p.Version) size += varint.UvarintSize(p.Codec) diff --git a/vendor/github.com/ipfs/go-cid/cid_fuzz.go b/vendor/github.com/ipfs/go-cid/cid_fuzz.go index 0b0408c07..af1ab46b5 100644 --- a/vendor/github.com/ipfs/go-cid/cid_fuzz.go +++ b/vendor/github.com/ipfs/go-cid/cid_fuzz.go @@ -1,5 +1,4 @@ //go:build gofuzz -// +build gofuzz package cid diff --git a/vendor/github.com/ipfs/go-cid/version.json b/vendor/github.com/ipfs/go-cid/version.json index 1437d5b73..908483a37 100644 --- a/vendor/github.com/ipfs/go-cid/version.json +++ b/vendor/github.com/ipfs/go-cid/version.json @@ -1,3 +1,3 @@ { - "version": "v0.2.0" + "version": "v0.3.2" } diff --git a/vendor/github.com/ipfs/go-datastore/.gitignore b/vendor/github.com/ipfs/go-datastore/.gitignore deleted file mode 100644 index 1377554eb..000000000 --- a/vendor/github.com/ipfs/go-datastore/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.swp diff --git a/vendor/github.com/ipfs/go-datastore/LICENSE b/vendor/github.com/ipfs/go-datastore/LICENSE deleted file mode 100644 index f20490238..000000000 --- a/vendor/github.com/ipfs/go-datastore/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License - -Copyright (c) 2016 Juan Batiz-Benet - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-datastore/README.md b/vendor/github.com/ipfs/go-datastore/README.md deleted file mode 100644 index 58df92b6d..000000000 --- a/vendor/github.com/ipfs/go-datastore/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# go-datastore - -[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](http://ipn.io) -[![](https://img.shields.io/badge/project-IPFS-blue.svg?style=flat-square)](http://ipfs.io/) -[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23ipfs) -[![standard-readme compliant](https://img.shields.io/badge/standard--readme-OK-green.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) -[![GoDoc](https://godoc.org/github.com/ipfs/go-datastore?status.svg)](https://godoc.org/github.com/ipfs/go-datastore) - -> key-value datastore interfaces - -## Lead Maintainer - -[Steven Allen](https://github.com/Stebalien) - -## Table of Contents - -- [Background](#background) -- [Documentation](#documentation) -- [Contribute](#contribute) -- [License](#license) - -## Background - -Datastore is a generic layer of abstraction for data store and database access. It is a simple API with the aim to enable application development in a datastore-agnostic way, allowing datastores to be swapped seamlessly without changing application code. Thus, one can leverage different datastores with different strengths without committing the application to one datastore throughout its lifetime. - -In addition, grouped datastores significantly simplify interesting data access patterns (such as caching and sharding). - -Based on [datastore.py](https://github.com/datastore/datastore). - -## Documentation - -https://godoc.org/github.com/ipfs/go-datastore - -## Contribute - -Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-datastore/issues)! - -This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). - -### Want to hack on IPFS? - -[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/contributing.md) - -## License - -MIT - diff --git a/vendor/github.com/ipfs/go-datastore/basic_ds.go b/vendor/github.com/ipfs/go-datastore/basic_ds.go deleted file mode 100644 index 95f03fe8c..000000000 --- a/vendor/github.com/ipfs/go-datastore/basic_ds.go +++ /dev/null @@ -1,304 +0,0 @@ -package datastore - -import ( - "context" - "log" - - dsq "github.com/ipfs/go-datastore/query" -) - -// Here are some basic datastore implementations. - -// MapDatastore uses a standard Go map for internal storage. -type MapDatastore struct { - values map[Key][]byte -} - -var _ Datastore = (*MapDatastore)(nil) -var _ Batching = (*MapDatastore)(nil) - -// NewMapDatastore constructs a MapDatastore. It is _not_ thread-safe by -// default, wrap using sync.MutexWrap if you need thread safety (the answer here -// is usually yes). -func NewMapDatastore() (d *MapDatastore) { - return &MapDatastore{ - values: make(map[Key][]byte), - } -} - -// Put implements Datastore.Put -func (d *MapDatastore) Put(ctx context.Context, key Key, value []byte) (err error) { - d.values[key] = value - return nil -} - -// Sync implements Datastore.Sync -func (d *MapDatastore) Sync(ctx context.Context, prefix Key) error { - return nil -} - -// Get implements Datastore.Get -func (d *MapDatastore) Get(ctx context.Context, key Key) (value []byte, err error) { - val, found := d.values[key] - if !found { - return nil, ErrNotFound - } - return val, nil -} - -// Has implements Datastore.Has -func (d *MapDatastore) Has(ctx context.Context, key Key) (exists bool, err error) { - _, found := d.values[key] - return found, nil -} - -// GetSize implements Datastore.GetSize -func (d *MapDatastore) GetSize(ctx context.Context, key Key) (size int, err error) { - if v, found := d.values[key]; found { - return len(v), nil - } - return -1, ErrNotFound -} - -// Delete implements Datastore.Delete -func (d *MapDatastore) Delete(ctx context.Context, key Key) (err error) { - delete(d.values, key) - return nil -} - -// Query implements Datastore.Query -func (d *MapDatastore) Query(ctx context.Context, q dsq.Query) (dsq.Results, error) { - re := make([]dsq.Entry, 0, len(d.values)) - for k, v := range d.values { - e := dsq.Entry{Key: k.String(), Size: len(v)} - if !q.KeysOnly { - e.Value = v - } - re = append(re, e) - } - r := dsq.ResultsWithEntries(q, re) - r = dsq.NaiveQueryApply(q, r) - return r, nil -} - -func (d *MapDatastore) Batch(ctx context.Context) (Batch, error) { - return NewBasicBatch(d), nil -} - -func (d *MapDatastore) Close() error { - return nil -} - -// NullDatastore stores nothing, but conforms to the API. -// Useful to test with. -type NullDatastore struct { -} - -var _ Datastore = (*NullDatastore)(nil) -var _ Batching = (*NullDatastore)(nil) - -// NewNullDatastore constructs a null datastoe -func NewNullDatastore() *NullDatastore { - return &NullDatastore{} -} - -// Put implements Datastore.Put -func (d *NullDatastore) Put(ctx context.Context, key Key, value []byte) (err error) { - return nil -} - -// Sync implements Datastore.Sync -func (d *NullDatastore) Sync(ctx context.Context, prefix Key) error { - return nil -} - -// Get implements Datastore.Get -func (d *NullDatastore) Get(ctx context.Context, key Key) (value []byte, err error) { - return nil, ErrNotFound -} - -// Has implements Datastore.Has -func (d *NullDatastore) Has(ctx context.Context, key Key) (exists bool, err error) { - return false, nil -} - -// Has implements Datastore.GetSize -func (d *NullDatastore) GetSize(ctx context.Context, key Key) (size int, err error) { - return -1, ErrNotFound -} - -// Delete implements Datastore.Delete -func (d *NullDatastore) Delete(ctx context.Context, key Key) (err error) { - return nil -} - -// Query implements Datastore.Query -func (d *NullDatastore) Query(ctx context.Context, q dsq.Query) (dsq.Results, error) { - return dsq.ResultsWithEntries(q, nil), nil -} - -func (d *NullDatastore) Batch(ctx context.Context) (Batch, error) { - return NewBasicBatch(d), nil -} - -func (d *NullDatastore) Close() error { - return nil -} - -// LogDatastore logs all accesses through the datastore. -type LogDatastore struct { - Name string - child Datastore -} - -var _ Datastore = (*LogDatastore)(nil) -var _ Batching = (*LogDatastore)(nil) -var _ GCDatastore = (*LogDatastore)(nil) -var _ PersistentDatastore = (*LogDatastore)(nil) -var _ ScrubbedDatastore = (*LogDatastore)(nil) -var _ CheckedDatastore = (*LogDatastore)(nil) -var _ Shim = (*LogDatastore)(nil) - -// Shim is a datastore which has a child. -type Shim interface { - Datastore - - Children() []Datastore -} - -// NewLogDatastore constructs a log datastore. -func NewLogDatastore(ds Datastore, name string) *LogDatastore { - if len(name) < 1 { - name = "LogDatastore" - } - return &LogDatastore{Name: name, child: ds} -} - -// Children implements Shim -func (d *LogDatastore) Children() []Datastore { - return []Datastore{d.child} -} - -// Put implements Datastore.Put -func (d *LogDatastore) Put(ctx context.Context, key Key, value []byte) (err error) { - log.Printf("%s: Put %s\n", d.Name, key) - // log.Printf("%s: Put %s ```%s```", d.Name, key, value) - return d.child.Put(ctx, key, value) -} - -// Sync implements Datastore.Sync -func (d *LogDatastore) Sync(ctx context.Context, prefix Key) error { - log.Printf("%s: Sync %s\n", d.Name, prefix) - return d.child.Sync(ctx, prefix) -} - -// Get implements Datastore.Get -func (d *LogDatastore) Get(ctx context.Context, key Key) (value []byte, err error) { - log.Printf("%s: Get %s\n", d.Name, key) - return d.child.Get(ctx, key) -} - -// Has implements Datastore.Has -func (d *LogDatastore) Has(ctx context.Context, key Key) (exists bool, err error) { - log.Printf("%s: Has %s\n", d.Name, key) - return d.child.Has(ctx, key) -} - -// GetSize implements Datastore.GetSize -func (d *LogDatastore) GetSize(ctx context.Context, key Key) (size int, err error) { - log.Printf("%s: GetSize %s\n", d.Name, key) - return d.child.GetSize(ctx, key) -} - -// Delete implements Datastore.Delete -func (d *LogDatastore) Delete(ctx context.Context, key Key) (err error) { - log.Printf("%s: Delete %s\n", d.Name, key) - return d.child.Delete(ctx, key) -} - -// DiskUsage implements the PersistentDatastore interface. -func (d *LogDatastore) DiskUsage(ctx context.Context) (uint64, error) { - log.Printf("%s: DiskUsage\n", d.Name) - return DiskUsage(ctx, d.child) -} - -// Query implements Datastore.Query -func (d *LogDatastore) Query(ctx context.Context, q dsq.Query) (dsq.Results, error) { - log.Printf("%s: Query\n", d.Name) - log.Printf("%s: q.Prefix: %s\n", d.Name, q.Prefix) - log.Printf("%s: q.KeysOnly: %v\n", d.Name, q.KeysOnly) - log.Printf("%s: q.Filters: %d\n", d.Name, len(q.Filters)) - log.Printf("%s: q.Orders: %d\n", d.Name, len(q.Orders)) - log.Printf("%s: q.Offset: %d\n", d.Name, q.Offset) - - return d.child.Query(ctx, q) -} - -// LogBatch logs all accesses through the batch. -type LogBatch struct { - Name string - child Batch -} - -var _ Batch = (*LogBatch)(nil) - -func (d *LogDatastore) Batch(ctx context.Context) (Batch, error) { - log.Printf("%s: Batch\n", d.Name) - if bds, ok := d.child.(Batching); ok { - b, err := bds.Batch(ctx) - - if err != nil { - return nil, err - } - return &LogBatch{ - Name: d.Name, - child: b, - }, nil - } - return nil, ErrBatchUnsupported -} - -// Put implements Batch.Put -func (d *LogBatch) Put(ctx context.Context, key Key, value []byte) (err error) { - log.Printf("%s: BatchPut %s\n", d.Name, key) - // log.Printf("%s: Put %s ```%s```", d.Name, key, value) - return d.child.Put(ctx, key, value) -} - -// Delete implements Batch.Delete -func (d *LogBatch) Delete(ctx context.Context, key Key) (err error) { - log.Printf("%s: BatchDelete %s\n", d.Name, key) - return d.child.Delete(ctx, key) -} - -// Commit implements Batch.Commit -func (d *LogBatch) Commit(ctx context.Context) (err error) { - log.Printf("%s: BatchCommit\n", d.Name) - return d.child.Commit(ctx) -} - -func (d *LogDatastore) Close() error { - log.Printf("%s: Close\n", d.Name) - return d.child.Close() -} - -func (d *LogDatastore) Check(ctx context.Context) error { - if c, ok := d.child.(CheckedDatastore); ok { - return c.Check(ctx) - } - return nil -} - -func (d *LogDatastore) Scrub(ctx context.Context) error { - if c, ok := d.child.(ScrubbedDatastore); ok { - return c.Scrub(ctx) - } - return nil -} - -func (d *LogDatastore) CollectGarbage(ctx context.Context) error { - if c, ok := d.child.(GCDatastore); ok { - return c.CollectGarbage(ctx) - } - return nil -} diff --git a/vendor/github.com/ipfs/go-datastore/batch.go b/vendor/github.com/ipfs/go-datastore/batch.go deleted file mode 100644 index 7dbd27ffd..000000000 --- a/vendor/github.com/ipfs/go-datastore/batch.go +++ /dev/null @@ -1,53 +0,0 @@ -package datastore - -import ( - "context" -) - -type op struct { - delete bool - value []byte -} - -// basicBatch implements the transaction interface for datastores who do -// not have any sort of underlying transactional support -type basicBatch struct { - ops map[Key]op - - target Datastore -} - -var _ Batch = (*basicBatch)(nil) - -func NewBasicBatch(ds Datastore) Batch { - return &basicBatch{ - ops: make(map[Key]op), - target: ds, - } -} - -func (bt *basicBatch) Put(ctx context.Context, key Key, val []byte) error { - bt.ops[key] = op{value: val} - return nil -} - -func (bt *basicBatch) Delete(ctx context.Context, key Key) error { - bt.ops[key] = op{delete: true} - return nil -} - -func (bt *basicBatch) Commit(ctx context.Context) error { - var err error - for k, op := range bt.ops { - if op.delete { - err = bt.target.Delete(ctx, k) - } else { - err = bt.target.Put(ctx, k, op.value) - } - if err != nil { - break - } - } - - return err -} diff --git a/vendor/github.com/ipfs/go-datastore/datastore.go b/vendor/github.com/ipfs/go-datastore/datastore.go deleted file mode 100644 index 0d075df62..000000000 --- a/vendor/github.com/ipfs/go-datastore/datastore.go +++ /dev/null @@ -1,252 +0,0 @@ -package datastore - -import ( - "context" - "errors" - "io" - "time" - - query "github.com/ipfs/go-datastore/query" -) - -/* -Datastore represents storage for any key-value pair. - -Datastores are general enough to be backed by all kinds of different storage: -in-memory caches, databases, a remote datastore, flat files on disk, etc. - -The general idea is to wrap a more complicated storage facility in a simple, -uniform interface, keeping the freedom of using the right tools for the job. -In particular, a Datastore can aggregate other datastores in interesting ways, -like sharded (to distribute load) or tiered access (caches before databases). - -While Datastores should be written general enough to accept all sorts of -values, some implementations will undoubtedly have to be specific (e.g. SQL -databases where fields should be decomposed into columns), particularly to -support queries efficiently. Moreover, certain datastores may enforce certain -types of values (e.g. requiring an io.Reader, a specific struct, etc) or -serialization formats (JSON, Protobufs, etc). - -IMPORTANT: No Datastore should ever Panic! This is a cross-module interface, -and thus it should behave predictably and handle exceptional conditions with -proper error reporting. Thus, all Datastore calls may return errors, which -should be checked by callers. -*/ -type Datastore interface { - Read - Write - // Sync guarantees that any Put or Delete calls under prefix that returned - // before Sync(prefix) was called will be observed after Sync(prefix) - // returns, even if the program crashes. If Put/Delete operations already - // satisfy these requirements then Sync may be a no-op. - // - // If the prefix fails to Sync this method returns an error. - Sync(ctx context.Context, prefix Key) error - io.Closer -} - -// Write is the write-side of the Datastore interface. -type Write interface { - // Put stores the object `value` named by `key`. - // - // The generalized Datastore interface does not impose a value type, - // allowing various datastore middleware implementations (which do not - // handle the values directly) to be composed together. - // - // Ultimately, the lowest-level datastore will need to do some value checking - // or risk getting incorrect values. It may also be useful to expose a more - // type-safe interface to your application, and do the checking up-front. - Put(ctx context.Context, key Key, value []byte) error - - // Delete removes the value for given `key`. If the key is not in the - // datastore, this method returns no error. - Delete(ctx context.Context, key Key) error -} - -// Read is the read-side of the Datastore interface. -type Read interface { - // Get retrieves the object `value` named by `key`. - // Get will return ErrNotFound if the key is not mapped to a value. - Get(ctx context.Context, key Key) (value []byte, err error) - - // Has returns whether the `key` is mapped to a `value`. - // In some contexts, it may be much cheaper only to check for existence of - // a value, rather than retrieving the value itself. (e.g. HTTP HEAD). - // The default implementation is found in `GetBackedHas`. - Has(ctx context.Context, key Key) (exists bool, err error) - - // GetSize returns the size of the `value` named by `key`. - // In some contexts, it may be much cheaper to only get the size of the - // value rather than retrieving the value itself. - GetSize(ctx context.Context, key Key) (size int, err error) - - // Query searches the datastore and returns a query result. This function - // may return before the query actually runs. To wait for the query: - // - // result, _ := ds.Query(q) - // - // // use the channel interface; result may come in at different times - // for entry := range result.Next() { ... } - // - // // or wait for the query to be completely done - // entries, _ := result.Rest() - // for entry := range entries { ... } - // - Query(ctx context.Context, q query.Query) (query.Results, error) -} - -// Batching datastores support deferred, grouped updates to the database. -// `Batch`es do NOT have transactional semantics: updates to the underlying -// datastore are not guaranteed to occur in the same iota of time. Similarly, -// batched updates will not be flushed to the underlying datastore until -// `Commit` has been called. `Txn`s from a `TxnDatastore` have all the -// capabilities of a `Batch`, but the reverse is NOT true. -type Batching interface { - Datastore - - Batch(ctx context.Context) (Batch, error) -} - -// ErrBatchUnsupported is returned if the by Batch if the Datastore doesn't -// actually support batching. -var ErrBatchUnsupported = errors.New("this datastore does not support batching") - -// CheckedDatastore is an interface that should be implemented by datastores -// which may need checking on-disk data integrity. -type CheckedDatastore interface { - Datastore - - Check(ctx context.Context) error -} - -// ScrubbedDatastore is an interface that should be implemented by datastores -// which want to provide a mechanism to check data integrity and/or -// error correction. -type ScrubbedDatastore interface { - Datastore - - Scrub(ctx context.Context) error -} - -// GCDatastore is an interface that should be implemented by datastores which -// don't free disk space by just removing data from them. -type GCDatastore interface { - Datastore - - CollectGarbage(ctx context.Context) error -} - -// PersistentDatastore is an interface that should be implemented by datastores -// which can report disk usage. -type PersistentDatastore interface { - Datastore - - // DiskUsage returns the space used by a datastore, in bytes. - DiskUsage(ctx context.Context) (uint64, error) -} - -// DiskUsage checks if a Datastore is a -// PersistentDatastore and returns its DiskUsage(), -// otherwise returns 0. -func DiskUsage(ctx context.Context, d Datastore) (uint64, error) { - persDs, ok := d.(PersistentDatastore) - if !ok { - return 0, nil - } - return persDs.DiskUsage(ctx) -} - -// TTLDatastore is an interface that should be implemented by datastores that -// support expiring entries. -type TTLDatastore interface { - Datastore - TTL -} - -// TTL encapulates the methods that deal with entries with time-to-live. -type TTL interface { - PutWithTTL(ctx context.Context, key Key, value []byte, ttl time.Duration) error - SetTTL(ctx context.Context, key Key, ttl time.Duration) error - GetExpiration(ctx context.Context, key Key) (time.Time, error) -} - -// Txn extends the Datastore type. Txns allow users to batch queries and -// mutations to the Datastore into atomic groups, or transactions. Actions -// performed on a transaction will not take hold until a successful call to -// Commit has been made. Likewise, transactions can be aborted by calling -// Discard before a successful Commit has been made. -type Txn interface { - Read - Write - - // Commit finalizes a transaction, attempting to commit it to the Datastore. - // May return an error if the transaction has gone stale. The presence of an - // error is an indication that the data was not committed to the Datastore. - Commit(ctx context.Context) error - // Discard throws away changes recorded in a transaction without committing - // them to the underlying Datastore. Any calls made to Discard after Commit - // has been successfully called will have no effect on the transaction and - // state of the Datastore, making it safe to defer. - Discard(ctx context.Context) -} - -// TxnDatastore is an interface that should be implemented by datastores that -// support transactions. -type TxnDatastore interface { - Datastore - - NewTransaction(ctx context.Context, readOnly bool) (Txn, error) -} - -// Errors - -type dsError struct { - error - isNotFound bool -} - -func (e *dsError) NotFound() bool { - return e.isNotFound -} - -// ErrNotFound is returned by Get and GetSize when a datastore does not map the -// given key to a value. -var ErrNotFound error = &dsError{error: errors.New("datastore: key not found"), isNotFound: true} - -// GetBackedHas provides a default Datastore.Has implementation. -// It exists so Datastore.Has implementations can use it, like so: -// -// func (*d SomeDatastore) Has(key Key) (exists bool, err error) { -// return GetBackedHas(d, key) -// } -func GetBackedHas(ctx context.Context, ds Read, key Key) (bool, error) { - _, err := ds.Get(ctx, key) - switch err { - case nil: - return true, nil - case ErrNotFound: - return false, nil - default: - return false, err - } -} - -// GetBackedSize provides a default Datastore.GetSize implementation. -// It exists so Datastore.GetSize implementations can use it, like so: -// -// func (*d SomeDatastore) GetSize(key Key) (size int, err error) { -// return GetBackedSize(d, key) -// } -func GetBackedSize(ctx context.Context, ds Read, key Key) (int, error) { - value, err := ds.Get(ctx, key) - if err == nil { - return len(value), nil - } - return -1, err -} - -type Batch interface { - Write - - Commit(ctx context.Context) error -} diff --git a/vendor/github.com/ipfs/go-datastore/key.go b/vendor/github.com/ipfs/go-datastore/key.go deleted file mode 100644 index 42cea3084..000000000 --- a/vendor/github.com/ipfs/go-datastore/key.go +++ /dev/null @@ -1,309 +0,0 @@ -package datastore - -import ( - "encoding/json" - "path" - "strings" - - dsq "github.com/ipfs/go-datastore/query" - - "github.com/google/uuid" -) - -/* -A Key represents the unique identifier of an object. -Our Key scheme is inspired by file systems and Google App Engine key model. - -Keys are meant to be unique across a system. Keys are hierarchical, -incorporating more and more specific namespaces. Thus keys can be deemed -'children' or 'ancestors' of other keys:: - - Key("/Comedy") - Key("/Comedy/MontyPython") - -Also, every namespace can be parametrized to embed relevant object -information. For example, the Key `name` (most specific namespace) could -include the object type:: - - Key("/Comedy/MontyPython/Actor:JohnCleese") - Key("/Comedy/MontyPython/Sketch:CheeseShop") - Key("/Comedy/MontyPython/Sketch:CheeseShop/Character:Mousebender") - -*/ -type Key struct { - string -} - -// NewKey constructs a key from string. it will clean the value. -func NewKey(s string) Key { - k := Key{s} - k.Clean() - return k -} - -// RawKey creates a new Key without safety checking the input. Use with care. -func RawKey(s string) Key { - // accept an empty string and fix it to avoid special cases - // elsewhere - if len(s) == 0 { - return Key{"/"} - } - - // perform a quick sanity check that the key is in the correct - // format, if it is not then it is a programmer error and it is - // okay to panic - if len(s) == 0 || s[0] != '/' || (len(s) > 1 && s[len(s)-1] == '/') { - panic("invalid datastore key: " + s) - } - - return Key{s} -} - -// KeyWithNamespaces constructs a key out of a namespace slice. -func KeyWithNamespaces(ns []string) Key { - return NewKey(strings.Join(ns, "/")) -} - -// Clean up a Key, using path.Clean. -func (k *Key) Clean() { - switch { - case len(k.string) == 0: - k.string = "/" - case k.string[0] == '/': - k.string = path.Clean(k.string) - default: - k.string = path.Clean("/" + k.string) - } -} - -// Strings is the string value of Key -func (k Key) String() string { - return k.string -} - -// Bytes returns the string value of Key as a []byte -func (k Key) Bytes() []byte { - return []byte(k.string) -} - -// Equal checks equality of two keys -func (k Key) Equal(k2 Key) bool { - return k.string == k2.string -} - -// Less checks whether this key is sorted lower than another. -func (k Key) Less(k2 Key) bool { - list1 := k.List() - list2 := k2.List() - for i, c1 := range list1 { - if len(list2) < (i + 1) { - return false - } - - c2 := list2[i] - if c1 < c2 { - return true - } else if c1 > c2 { - return false - } - // c1 == c2, continue - } - - // list1 is shorter or exactly the same. - return len(list1) < len(list2) -} - -// List returns the `list` representation of this Key. -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").List() -// ["Comedy", "MontyPythong", "Actor:JohnCleese"] -func (k Key) List() []string { - return strings.Split(k.string, "/")[1:] -} - -// Reverse returns the reverse of this Key. -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Reverse() -// NewKey("/Actor:JohnCleese/MontyPython/Comedy") -func (k Key) Reverse() Key { - l := k.List() - r := make([]string, len(l)) - for i, e := range l { - r[len(l)-i-1] = e - } - return KeyWithNamespaces(r) -} - -// Namespaces returns the `namespaces` making up this Key. -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Namespaces() -// ["Comedy", "MontyPython", "Actor:JohnCleese"] -func (k Key) Namespaces() []string { - return k.List() -} - -// BaseNamespace returns the "base" namespace of this key (path.Base(filename)) -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").BaseNamespace() -// "Actor:JohnCleese" -func (k Key) BaseNamespace() string { - n := k.Namespaces() - return n[len(n)-1] -} - -// Type returns the "type" of this key (value of last namespace). -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Type() -// "Actor" -func (k Key) Type() string { - return NamespaceType(k.BaseNamespace()) -} - -// Name returns the "name" of this key (field of last namespace). -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Name() -// "JohnCleese" -func (k Key) Name() string { - return NamespaceValue(k.BaseNamespace()) -} - -// Instance returns an "instance" of this type key (appends value to namespace). -// NewKey("/Comedy/MontyPython/Actor").Instance("JohnClesse") -// NewKey("/Comedy/MontyPython/Actor:JohnCleese") -func (k Key) Instance(s string) Key { - return NewKey(k.string + ":" + s) -} - -// Path returns the "path" of this key (parent + type). -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Path() -// NewKey("/Comedy/MontyPython/Actor") -func (k Key) Path() Key { - s := k.Parent().string + "/" + NamespaceType(k.BaseNamespace()) - return NewKey(s) -} - -// Parent returns the `parent` Key of this Key. -// NewKey("/Comedy/MontyPython/Actor:JohnCleese").Parent() -// NewKey("/Comedy/MontyPython") -func (k Key) Parent() Key { - n := k.List() - if len(n) == 1 { - return RawKey("/") - } - return NewKey(strings.Join(n[:len(n)-1], "/")) -} - -// Child returns the `child` Key of this Key. -// NewKey("/Comedy/MontyPython").Child(NewKey("Actor:JohnCleese")) -// NewKey("/Comedy/MontyPython/Actor:JohnCleese") -func (k Key) Child(k2 Key) Key { - switch { - case k.string == "/": - return k2 - case k2.string == "/": - return k - default: - return RawKey(k.string + k2.string) - } -} - -// ChildString returns the `child` Key of this Key -- string helper. -// NewKey("/Comedy/MontyPython").ChildString("Actor:JohnCleese") -// NewKey("/Comedy/MontyPython/Actor:JohnCleese") -func (k Key) ChildString(s string) Key { - return NewKey(k.string + "/" + s) -} - -// IsAncestorOf returns whether this key is a prefix of `other` -// NewKey("/Comedy").IsAncestorOf("/Comedy/MontyPython") -// true -func (k Key) IsAncestorOf(other Key) bool { - // equivalent to HasPrefix(other, k.string + "/") - - if len(other.string) <= len(k.string) { - // We're not long enough to be a child. - return false - } - - if k.string == "/" { - // We're the root and the other key is longer. - return true - } - - // "other" starts with /k.string/ - return other.string[len(k.string)] == '/' && other.string[:len(k.string)] == k.string -} - -// IsDescendantOf returns whether this key contains another as a prefix. -// NewKey("/Comedy/MontyPython").IsDescendantOf("/Comedy") -// true -func (k Key) IsDescendantOf(other Key) bool { - return other.IsAncestorOf(k) -} - -// IsTopLevel returns whether this key has only one namespace. -func (k Key) IsTopLevel() bool { - return len(k.List()) == 1 -} - -// MarshalJSON implements the json.Marshaler interface, -// keys are represented as JSON strings -func (k Key) MarshalJSON() ([]byte, error) { - return json.Marshal(k.String()) -} - -// UnmarshalJSON implements the json.Unmarshaler interface, -// keys will parse any value specified as a key to a string -func (k *Key) UnmarshalJSON(data []byte) error { - var key string - if err := json.Unmarshal(data, &key); err != nil { - return err - } - *k = NewKey(key) - return nil -} - -// RandomKey returns a randomly (uuid) generated key. -// RandomKey() -// NewKey("/f98719ea086343f7b71f32ea9d9d521d") -func RandomKey() Key { - return NewKey(strings.Replace(uuid.New().String(), "-", "", -1)) -} - -/* -A Key Namespace is like a path element. -A namespace can optionally include a type (delimited by ':') - - > NamespaceValue("Song:PhilosopherSong") - PhilosopherSong - > NamespaceType("Song:PhilosopherSong") - Song - > NamespaceType("Music:Song:PhilosopherSong") - Music:Song -*/ - -// NamespaceType is the first component of a namespace. `foo` in `foo:bar` -func NamespaceType(namespace string) string { - parts := strings.Split(namespace, ":") - if len(parts) < 2 { - return "" - } - return strings.Join(parts[0:len(parts)-1], ":") -} - -// NamespaceValue returns the last component of a namespace. `baz` in `f:b:baz` -func NamespaceValue(namespace string) string { - parts := strings.Split(namespace, ":") - return parts[len(parts)-1] -} - -// KeySlice attaches the methods of sort.Interface to []Key, -// sorting in increasing order. -type KeySlice []Key - -func (p KeySlice) Len() int { return len(p) } -func (p KeySlice) Less(i, j int) bool { return p[i].Less(p[j]) } -func (p KeySlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } - -// EntryKeys -func EntryKeys(e []dsq.Entry) []Key { - ks := make([]Key, len(e)) - for i, e := range e { - ks[i] = NewKey(e.Key) - } - return ks -} diff --git a/vendor/github.com/ipfs/go-datastore/query/filter.go b/vendor/github.com/ipfs/go-datastore/query/filter.go deleted file mode 100644 index 1935c4888..000000000 --- a/vendor/github.com/ipfs/go-datastore/query/filter.go +++ /dev/null @@ -1,102 +0,0 @@ -package query - -import ( - "bytes" - "fmt" - "strings" -) - -// Filter is an object that tests ResultEntries -type Filter interface { - // Filter returns whether an entry passes the filter - Filter(e Entry) bool -} - -// Op is a comparison operator -type Op string - -var ( - Equal = Op("==") - NotEqual = Op("!=") - GreaterThan = Op(">") - GreaterThanOrEqual = Op(">=") - LessThan = Op("<") - LessThanOrEqual = Op("<=") -) - -// FilterValueCompare is used to signal to datastores they -// should apply internal comparisons. unfortunately, there -// is no way to apply comparisons* to interface{} types in -// Go, so if the datastore doesnt have a special way to -// handle these comparisons, you must provided the -// TypedFilter to actually do filtering. -// -// [*] other than == and !=, which use reflect.DeepEqual. -type FilterValueCompare struct { - Op Op - Value []byte -} - -func (f FilterValueCompare) Filter(e Entry) bool { - cmp := bytes.Compare(e.Value, f.Value) - switch f.Op { - case Equal: - return cmp == 0 - case NotEqual: - return cmp != 0 - case LessThan: - return cmp < 0 - case LessThanOrEqual: - return cmp <= 0 - case GreaterThan: - return cmp > 0 - case GreaterThanOrEqual: - return cmp >= 0 - default: - panic(fmt.Errorf("unknown operation: %s", f.Op)) - } -} - -func (f FilterValueCompare) String() string { - return fmt.Sprintf("VALUE %s %q", f.Op, string(f.Value)) -} - -type FilterKeyCompare struct { - Op Op - Key string -} - -func (f FilterKeyCompare) Filter(e Entry) bool { - switch f.Op { - case Equal: - return e.Key == f.Key - case NotEqual: - return e.Key != f.Key - case GreaterThan: - return e.Key > f.Key - case GreaterThanOrEqual: - return e.Key >= f.Key - case LessThan: - return e.Key < f.Key - case LessThanOrEqual: - return e.Key <= f.Key - default: - panic(fmt.Errorf("unknown op '%s'", f.Op)) - } -} - -func (f FilterKeyCompare) String() string { - return fmt.Sprintf("KEY %s %q", f.Op, f.Key) -} - -type FilterKeyPrefix struct { - Prefix string -} - -func (f FilterKeyPrefix) Filter(e Entry) bool { - return strings.HasPrefix(e.Key, f.Prefix) -} - -func (f FilterKeyPrefix) String() string { - return fmt.Sprintf("PREFIX(%q)", f.Prefix) -} diff --git a/vendor/github.com/ipfs/go-datastore/query/order.go b/vendor/github.com/ipfs/go-datastore/query/order.go deleted file mode 100644 index 19931557e..000000000 --- a/vendor/github.com/ipfs/go-datastore/query/order.go +++ /dev/null @@ -1,94 +0,0 @@ -package query - -import ( - "bytes" - "sort" - "strings" -) - -// Order is an object used to order objects -type Order interface { - Compare(a, b Entry) int -} - -// OrderByFunction orders the results based on the result of the given function. -type OrderByFunction func(a, b Entry) int - -func (o OrderByFunction) Compare(a, b Entry) int { - return o(a, b) -} - -func (OrderByFunction) String() string { - return "FN" -} - -// OrderByValue is used to signal to datastores they should apply internal -// orderings. -type OrderByValue struct{} - -func (o OrderByValue) Compare(a, b Entry) int { - return bytes.Compare(a.Value, b.Value) -} - -func (OrderByValue) String() string { - return "VALUE" -} - -// OrderByValueDescending is used to signal to datastores they -// should apply internal orderings. -type OrderByValueDescending struct{} - -func (o OrderByValueDescending) Compare(a, b Entry) int { - return -bytes.Compare(a.Value, b.Value) -} - -func (OrderByValueDescending) String() string { - return "desc(VALUE)" -} - -// OrderByKey -type OrderByKey struct{} - -func (o OrderByKey) Compare(a, b Entry) int { - return strings.Compare(a.Key, b.Key) -} - -func (OrderByKey) String() string { - return "KEY" -} - -// OrderByKeyDescending -type OrderByKeyDescending struct{} - -func (o OrderByKeyDescending) Compare(a, b Entry) int { - return -strings.Compare(a.Key, b.Key) -} - -func (OrderByKeyDescending) String() string { - return "desc(KEY)" -} - -// Less returns true if a comes before b with the requested orderings. -func Less(orders []Order, a, b Entry) bool { - for _, cmp := range orders { - switch cmp.Compare(a, b) { - case 0: - case -1: - return true - case 1: - return false - } - } - - // This gives us a *stable* sort for free. We don't care - // preserving the order from the underlying datastore - // because it's undefined. - return a.Key < b.Key -} - -// Sort sorts the given entries using the given orders. -func Sort(orders []Order, entries []Entry) { - sort.Slice(entries, func(i int, j int) bool { - return Less(orders, entries[i], entries[j]) - }) -} diff --git a/vendor/github.com/ipfs/go-datastore/query/query.go b/vendor/github.com/ipfs/go-datastore/query/query.go deleted file mode 100644 index a390e5bf3..000000000 --- a/vendor/github.com/ipfs/go-datastore/query/query.go +++ /dev/null @@ -1,426 +0,0 @@ -package query - -import ( - "fmt" - "time" - - goprocess "github.com/jbenet/goprocess" -) - -/* -Query represents storage for any key-value pair. - -tl;dr: - - queries are supported across datastores. - Cheap on top of relational dbs, and expensive otherwise. - Pick the right tool for the job! - -In addition to the key-value store get and set semantics, datastore -provides an interface to retrieve multiple records at a time through -the use of queries. The datastore Query model gleans a common set of -operations performed when querying. To avoid pasting here years of -database research, let’s summarize the operations datastore supports. - -Query Operations, applied in-order: - - * prefix - scope the query to a given path prefix - * filters - select a subset of values by applying constraints - * orders - sort the results by applying sort conditions, hierarchically. - * offset - skip a number of results (for efficient pagination) - * limit - impose a numeric limit on the number of results - -Datastore combines these operations into a simple Query class that allows -applications to define their constraints in a simple, generic, way without -introducing datastore specific calls, languages, etc. - -However, take heed: not all datastores support efficiently performing these -operations. Pick a datastore based on your needs. If you need efficient look-ups, -go for a simple key/value store. If you need efficient queries, consider an SQL -backed datastore. - -Notes: - - * Prefix: When a query filters by prefix, it selects keys that are strict - children of the prefix. For example, a prefix "/foo" would select "/foo/bar" - but not "/foobar" or "/foo", - * Orders: Orders are applied hierarchically. Results are sorted by the first - ordering, then entries equal under the first ordering are sorted with the - second ordering, etc. - * Limits & Offset: Limits and offsets are applied after everything else. -*/ -type Query struct { - Prefix string // namespaces the query to results whose keys have Prefix - Filters []Filter // filter results. apply sequentially - Orders []Order // order results. apply hierarchically - Limit int // maximum number of results - Offset int // skip given number of results - KeysOnly bool // return only keys. - ReturnExpirations bool // return expirations (see TTLDatastore) - ReturnsSizes bool // always return sizes. If not set, datastore impl can return - // // it anyway if it doesn't involve a performance cost. If KeysOnly - // // is not set, Size should always be set. -} - -// String returns a string representation of the Query for debugging/validation -// purposes. Do not use it for SQL queries. -func (q Query) String() string { - s := "SELECT keys" - if !q.KeysOnly { - s += ",vals" - } - if q.ReturnExpirations { - s += ",exps" - } - - s += " " - - if q.Prefix != "" { - s += fmt.Sprintf("FROM %q ", q.Prefix) - } - - if len(q.Filters) > 0 { - s += fmt.Sprintf("FILTER [%s", q.Filters[0]) - for _, f := range q.Filters[1:] { - s += fmt.Sprintf(", %s", f) - } - s += "] " - } - - if len(q.Orders) > 0 { - s += fmt.Sprintf("ORDER [%s", q.Orders[0]) - for _, f := range q.Orders[1:] { - s += fmt.Sprintf(", %s", f) - } - s += "] " - } - - if q.Offset > 0 { - s += fmt.Sprintf("OFFSET %d ", q.Offset) - } - - if q.Limit > 0 { - s += fmt.Sprintf("LIMIT %d ", q.Limit) - } - // Will always end with a space, strip it. - return s[:len(s)-1] -} - -// Entry is a query result entry. -type Entry struct { - Key string // cant be ds.Key because circular imports ...!!! - Value []byte // Will be nil if KeysOnly has been passed. - Expiration time.Time // Entry expiration timestamp if requested and supported (see TTLDatastore). - Size int // Might be -1 if the datastore doesn't support listing the size with KeysOnly - // // or if ReturnsSizes is not set -} - -// Result is a special entry that includes an error, so that the client -// may be warned about internal errors. If Error is non-nil, Entry must be -// empty. -type Result struct { - Entry - - Error error -} - -// Results is a set of Query results. This is the interface for clients. -// Example: -// -// qr, _ := myds.Query(q) -// for r := range qr.Next() { -// if r.Error != nil { -// // handle. -// break -// } -// -// fmt.Println(r.Entry.Key, r.Entry.Value) -// } -// -// or, wait on all results at once: -// -// qr, _ := myds.Query(q) -// es, _ := qr.Rest() -// for _, e := range es { -// fmt.Println(e.Key, e.Value) -// } -// -type Results interface { - Query() Query // the query these Results correspond to - Next() <-chan Result // returns a channel to wait for the next result - NextSync() (Result, bool) // blocks and waits to return the next result, second parameter returns false when results are exhausted - Rest() ([]Entry, error) // waits till processing finishes, returns all entries at once. - Close() error // client may call Close to signal early exit - - // Process returns a goprocess.Process associated with these results. - // most users will not need this function (Close is all they want), - // but it's here in case you want to connect the results to other - // goprocess-friendly things. - Process() goprocess.Process -} - -// results implements Results -type results struct { - query Query - proc goprocess.Process - res <-chan Result -} - -func (r *results) Next() <-chan Result { - return r.res -} - -func (r *results) NextSync() (Result, bool) { - val, ok := <-r.res - return val, ok -} - -func (r *results) Rest() ([]Entry, error) { - var es []Entry - for e := range r.res { - if e.Error != nil { - return es, e.Error - } - es = append(es, e.Entry) - } - <-r.proc.Closed() // wait till the processing finishes. - return es, nil -} - -func (r *results) Process() goprocess.Process { - return r.proc -} - -func (r *results) Close() error { - return r.proc.Close() -} - -func (r *results) Query() Query { - return r.query -} - -// ResultBuilder is what implementors use to construct results -// Implementors of datastores and their clients must respect the -// Process of the Request: -// -// * clients must call r.Process().Close() on an early exit, so -// implementations can reclaim resources. -// * if the Entries are read to completion (channel closed), Process -// should be closed automatically. -// * datastores must respect <-Process.Closing(), which intermediates -// an early close signal from the client. -// -type ResultBuilder struct { - Query Query - Process goprocess.Process - Output chan Result -} - -// Results returns a Results to to this builder. -func (rb *ResultBuilder) Results() Results { - return &results{ - query: rb.Query, - proc: rb.Process, - res: rb.Output, - } -} - -const NormalBufSize = 1 -const KeysOnlyBufSize = 128 - -func NewResultBuilder(q Query) *ResultBuilder { - bufSize := NormalBufSize - if q.KeysOnly { - bufSize = KeysOnlyBufSize - } - b := &ResultBuilder{ - Query: q, - Output: make(chan Result, bufSize), - } - b.Process = goprocess.WithTeardown(func() error { - close(b.Output) - return nil - }) - return b -} - -// ResultsWithChan returns a Results object from a channel -// of Result entries. -// -// DEPRECATED: This iterator is impossible to cancel correctly. Canceling it -// will leave anything trying to write to the result channel hanging. -func ResultsWithChan(q Query, res <-chan Result) Results { - return ResultsWithProcess(q, func(worker goprocess.Process, out chan<- Result) { - for { - select { - case <-worker.Closing(): // client told us to close early - return - case e, more := <-res: - if !more { - return - } - - select { - case out <- e: - case <-worker.Closing(): // client told us to close early - return - } - } - } - }) -} - -// ResultsWithProcess returns a Results object with the results generated by the -// passed subprocess. -func ResultsWithProcess(q Query, proc func(goprocess.Process, chan<- Result)) Results { - b := NewResultBuilder(q) - - // go consume all the entries and add them to the results. - b.Process.Go(func(worker goprocess.Process) { - proc(worker, b.Output) - }) - - go b.Process.CloseAfterChildren() //nolint - return b.Results() -} - -// ResultsWithEntries returns a Results object from a list of entries -func ResultsWithEntries(q Query, res []Entry) Results { - i := 0 - return ResultsFromIterator(q, Iterator{ - Next: func() (Result, bool) { - if i >= len(res) { - return Result{}, false - } - next := res[i] - i++ - return Result{Entry: next}, true - }, - }) -} - -func ResultsReplaceQuery(r Results, q Query) Results { - switch r := r.(type) { - case *results: - // note: not using field names to make sure all fields are copied - return &results{q, r.proc, r.res} - case *resultsIter: - // note: not using field names to make sure all fields are copied - lr := r.legacyResults - if lr != nil { - lr = &results{q, lr.proc, lr.res} - } - return &resultsIter{q, r.next, r.close, lr} - default: - panic("unknown results type") - } -} - -// -// ResultFromIterator provides an alternative way to to construct -// results without the use of channels. -// - -func ResultsFromIterator(q Query, iter Iterator) Results { - if iter.Close == nil { - iter.Close = noopClose - } - return &resultsIter{ - query: q, - next: iter.Next, - close: iter.Close, - } -} - -func noopClose() error { - return nil -} - -type Iterator struct { - Next func() (Result, bool) - Close func() error // note: might be called more than once -} - -type resultsIter struct { - query Query - next func() (Result, bool) - close func() error - legacyResults *results -} - -func (r *resultsIter) Next() <-chan Result { - r.useLegacyResults() - return r.legacyResults.Next() -} - -func (r *resultsIter) NextSync() (Result, bool) { - if r.legacyResults != nil { - return r.legacyResults.NextSync() - } else { - res, ok := r.next() - if !ok { - r.close() - } - return res, ok - } -} - -func (r *resultsIter) Rest() ([]Entry, error) { - var es []Entry - for { - e, ok := r.NextSync() - if !ok { - break - } - if e.Error != nil { - return es, e.Error - } - es = append(es, e.Entry) - } - return es, nil -} - -func (r *resultsIter) Process() goprocess.Process { - r.useLegacyResults() - return r.legacyResults.Process() -} - -func (r *resultsIter) Close() error { - if r.legacyResults != nil { - return r.legacyResults.Close() - } else { - return r.close() - } -} - -func (r *resultsIter) Query() Query { - return r.query -} - -func (r *resultsIter) useLegacyResults() { - if r.legacyResults != nil { - return - } - - b := NewResultBuilder(r.query) - - // go consume all the entries and add them to the results. - b.Process.Go(func(worker goprocess.Process) { - defer r.close() - for { - e, ok := r.next() - if !ok { - break - } - select { - case b.Output <- e: - case <-worker.Closing(): // client told us to close early - return - } - } - }) - - go b.Process.CloseAfterChildren() //nolint - - r.legacyResults = b.Results().(*results) -} diff --git a/vendor/github.com/ipfs/go-datastore/query/query_impl.go b/vendor/github.com/ipfs/go-datastore/query/query_impl.go deleted file mode 100644 index dd554e743..000000000 --- a/vendor/github.com/ipfs/go-datastore/query/query_impl.go +++ /dev/null @@ -1,158 +0,0 @@ -package query - -import ( - "path" - - goprocess "github.com/jbenet/goprocess" -) - -// NaiveFilter applies a filter to the results. -func NaiveFilter(qr Results, filter Filter) Results { - return ResultsFromIterator(qr.Query(), Iterator{ - Next: func() (Result, bool) { - for { - e, ok := qr.NextSync() - if !ok { - return Result{}, false - } - if e.Error != nil || filter.Filter(e.Entry) { - return e, true - } - } - }, - Close: func() error { - return qr.Close() - }, - }) -} - -// NaiveLimit truncates the results to a given int limit -func NaiveLimit(qr Results, limit int) Results { - if limit == 0 { - // 0 means no limit - return qr - } - closed := false - return ResultsFromIterator(qr.Query(), Iterator{ - Next: func() (Result, bool) { - if limit == 0 { - if !closed { - closed = true - err := qr.Close() - if err != nil { - return Result{Error: err}, true - } - } - return Result{}, false - } - limit-- - return qr.NextSync() - }, - Close: func() error { - if closed { - return nil - } - closed = true - return qr.Close() - }, - }) -} - -// NaiveOffset skips a given number of results -func NaiveOffset(qr Results, offset int) Results { - return ResultsFromIterator(qr.Query(), Iterator{ - Next: func() (Result, bool) { - for ; offset > 0; offset-- { - res, ok := qr.NextSync() - if !ok || res.Error != nil { - return res, ok - } - } - return qr.NextSync() - }, - Close: func() error { - return qr.Close() - }, - }) -} - -// NaiveOrder reorders results according to given orders. -// WARNING: this is the only non-stream friendly operation! -func NaiveOrder(qr Results, orders ...Order) Results { - // Short circuit. - if len(orders) == 0 { - return qr - } - - return ResultsWithProcess(qr.Query(), func(worker goprocess.Process, out chan<- Result) { - defer qr.Close() - var entries []Entry - collect: - for { - select { - case <-worker.Closing(): - return - case e, ok := <-qr.Next(): - if !ok { - break collect - } - if e.Error != nil { - out <- e - continue - } - entries = append(entries, e.Entry) - } - } - - Sort(orders, entries) - - for _, e := range entries { - select { - case <-worker.Closing(): - return - case out <- Result{Entry: e}: - } - } - }) -} - -func NaiveQueryApply(q Query, qr Results) Results { - if q.Prefix != "" { - // Clean the prefix as a key and append / so a prefix of /bar - // only finds /bar/baz, not /barbaz. - prefix := q.Prefix - if len(prefix) == 0 { - prefix = "/" - } else { - if prefix[0] != '/' { - prefix = "/" + prefix - } - prefix = path.Clean(prefix) - } - // If the prefix is empty, ignore it. - if prefix != "/" { - qr = NaiveFilter(qr, FilterKeyPrefix{prefix + "/"}) - } - } - for _, f := range q.Filters { - qr = NaiveFilter(qr, f) - } - if len(q.Orders) > 0 { - qr = NaiveOrder(qr, q.Orders...) - } - if q.Offset != 0 { - qr = NaiveOffset(qr, q.Offset) - } - if q.Limit != 0 { - qr = NaiveLimit(qr, q.Limit) - } - return qr -} - -func ResultEntriesFrom(keys []string, vals [][]byte) []Entry { - re := make([]Entry, len(keys)) - for i, k := range keys { - re[i] = Entry{Key: k, Size: len(vals[i]), Value: vals[i]} - } - return re -} diff --git a/vendor/github.com/ipfs/go-datastore/version.json b/vendor/github.com/ipfs/go-datastore/version.json deleted file mode 100644 index 4ab5086b7..000000000 --- a/vendor/github.com/ipfs/go-datastore/version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "version": "v0.5.1" -} diff --git a/vendor/github.com/ipfs/go-ds-sql/LICENSE b/vendor/github.com/ipfs/go-ds-sql/LICENSE deleted file mode 100644 index 26100332b..000000000 --- a/vendor/github.com/ipfs/go-ds-sql/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Jeromy Johnson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/ipfs/go-ds-sql/README.md b/vendor/github.com/ipfs/go-ds-sql/README.md deleted file mode 100644 index 1ad53fa14..000000000 --- a/vendor/github.com/ipfs/go-ds-sql/README.md +++ /dev/null @@ -1,130 +0,0 @@ -# SQL Datastore - -[![CircleCI](https://circleci.com/gh/ipfs/go-ds-sql.svg?style=shield)](https://circleci.com/gh/ipfs/go-ds-sql) -[![Coverage](https://codecov.io/gh/ipfs/go-ds-sql/branch/master/graph/badge.svg)](https://codecov.io/gh/ipfs/go-ds-sql) -[![Standard README](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg)](https://github.com/RichardLitt/standard-readme) -[![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://godoc.org/github.com/ipfs/go-ds-sql) -[![golang version](https://img.shields.io/badge/golang-%3E%3D1.14.0-orange.svg)](https://golang.org/) -[![Go Report Card](https://goreportcard.com/badge/github.com/ipfs/go-ds-sql)](https://goreportcard.com/report/github.com/ipfs/go-ds-sql) - -An implementation of [the datastore interface](https://github.com/ipfs/go-datastore) -that can be backed by any sql database. - -## Install - -```sh -go get github.com/ipfs/go-ds-sql -``` - -## Usage - -### PostgreSQL - -Ensure a database is created and a table exists with `key` and `data` columns. For example, in PostgreSQL you can create a table with the following structure (replacing `table_name` with the name of the table the datastore will use - by default this is `blocks`): - -```sql -CREATE TABLE IF NOT EXISTS table_name (key TEXT NOT NULL UNIQUE, data BYTEA) -``` - -It's recommended to create an index on the `key` column that is optimised for prefix scans. For example, in PostgreSQL you can create a `text_pattern_ops` index on the table: - -```sql -CREATE INDEX IF NOT EXISTS table_name_key_text_pattern_ops_idx ON table_name (key text_pattern_ops) -``` - -Import and use in your application: - -```go -import ( - "database/sql" - "github.com/ipfs/go-ds-sql" - pg "github.com/ipfs/go-ds-sql/postgres" -) - -mydb, _ := sql.Open("yourdb", "yourdbparameters") - -// Implement the Queries interface for your SQL impl. -// ...or use the provided PostgreSQL queries -queries := pg.NewQueries("blocks") - -ds := sqlds.NewDatastore(mydb, queries) -``` - -### SQLite - -The [SQLite](https://sqlite.org) wrapper tries to create the table automatically - -Prefix scans are optimized by using GLOB - -Import and use in your application: - -```go -package main - -import ( - sqliteds "github.com/ipfs/go-ds-sql/sqlite" - _ "github.com/mattn/go-sqlite3" -) - -func main() { - opts := &sqliteds.Options{ - DSN: "db.sqlite", - } - - ds, err := opts.Create() - if err != nil { - panic(err) - } - defer func() { - if err := ds.Close(); err != nil { - panic(err) - } - }() -} -``` - -If no `DSN` is specified, an unique in-memory database will be created - -### SQLCipher - -The SQLite wrapper also supports the [SQLCipher](https://www.zetetic.net/sqlcipher/) extension - -Import and use in your application: - -```go -package main - -import ( - sqliteds "github.com/ipfs/go-ds-sql/sqlite" - _ "github.com/mutecomm/go-sqlcipher/v4" -) - -func main() { - opts := &sqliteds.Options{ - DSN: "encdb.sqlite", - Key: ([]byte)("32_very_secure_bytes_0123456789a"), - } - - ds, err := opts.Create() - if err != nil { - panic(err) - } - defer func() { - if err := ds.Close(); err != nil { - panic(err) - } - }() -} -``` - -## API - -[GoDoc Reference](https://godoc.org/github.com/ipfs/go-ds-sql) - -## Contribute - -Feel free to dive in! [Open an issue](https://github.com/ipfs/go-ds-sql/issues/new) or submit PRs. - -## License - -[MIT](LICENSE) diff --git a/vendor/github.com/ipfs/go-ds-sql/batching.go b/vendor/github.com/ipfs/go-ds-sql/batching.go deleted file mode 100644 index a9903663e..000000000 --- a/vendor/github.com/ipfs/go-ds-sql/batching.go +++ /dev/null @@ -1,65 +0,0 @@ -package sqlds - -import ( - "context" - - ds "github.com/ipfs/go-datastore" -) - -type op struct { - delete bool - value []byte -} - -type batch struct { - ds *Datastore - ops map[ds.Key]op -} - -// Batch creates a set of deferred updates to the database. -// Since SQL does not support a true batch of updates, -// operations are buffered and then executed sequentially -// over a single connection when Commit is called. -func (d *Datastore) Batch(ctx context.Context) (ds.Batch, error) { - return &batch{ - ds: d, - ops: make(map[ds.Key]op), - }, nil -} - -func (bt *batch) Put(ctx context.Context, key ds.Key, val []byte) error { - bt.ops[key] = op{value: val} - return nil -} - -func (bt *batch) Delete(ctx context.Context, key ds.Key) error { - bt.ops[key] = op{delete: true} - return nil -} - -func (bt *batch) Commit(ctx context.Context) error { - return bt.CommitContext(ctx) -} - -func (bt *batch) CommitContext(ctx context.Context) error { - conn, err := bt.ds.db.Conn(ctx) - if err != nil { - return err - } - defer conn.Close() - - for k, op := range bt.ops { - if op.delete { - _, err = conn.ExecContext(ctx, bt.ds.queries.Delete(), k.String()) - } else { - _, err = conn.ExecContext(ctx, bt.ds.queries.Put(), k.String(), op.value) - } - if err != nil { - break - } - } - - return err -} - -var _ ds.Batching = (*Datastore)(nil) diff --git a/vendor/github.com/ipfs/go-ds-sql/dstore.go b/vendor/github.com/ipfs/go-ds-sql/dstore.go deleted file mode 100644 index efd5bc552..000000000 --- a/vendor/github.com/ipfs/go-ds-sql/dstore.go +++ /dev/null @@ -1,204 +0,0 @@ -package sqlds - -import ( - "context" - "database/sql" - "fmt" - - ds "github.com/ipfs/go-datastore" - dsq "github.com/ipfs/go-datastore/query" -) - -// Queries generates SQL queries for datastore operations. -type Queries interface { - Delete() string - Exists() string - Get() string - Put() string - Query() string - Prefix() string - Limit() string - Offset() string - GetSize() string -} - -// Datastore is a SQL backed datastore. -type Datastore struct { - db *sql.DB - queries Queries -} - -// NewDatastore returns a new SQL datastore. -func NewDatastore(db *sql.DB, queries Queries) *Datastore { - return &Datastore{db: db, queries: queries} -} - -// Close closes the underying SQL database. -func (d *Datastore) Close() error { - return d.db.Close() -} - -// Delete removes a row from the SQL database by the given key. -func (d *Datastore) Delete(ctx context.Context, key ds.Key) error { - _, err := d.db.ExecContext(ctx, d.queries.Delete(), key.String()) - if err != nil { - return err - } - - return nil -} - -// Get retrieves a value from the SQL database by the given key. -func (d *Datastore) Get(ctx context.Context, key ds.Key) (value []byte, err error) { - row := d.db.QueryRowContext(ctx, d.queries.Get(), key.String()) - var out []byte - - switch err := row.Scan(&out); err { - case sql.ErrNoRows: - return nil, ds.ErrNotFound - case nil: - return out, nil - default: - return nil, err - } -} - -// Has determines if a value for the given key exists in the SQL database. -func (d *Datastore) Has(ctx context.Context, key ds.Key) (exists bool, err error) { - row := d.db.QueryRowContext(ctx, d.queries.Exists(), key.String()) - - switch err := row.Scan(&exists); err { - case sql.ErrNoRows: - return exists, nil - case nil: - return exists, nil - default: - return exists, err - } -} - -// Put "upserts" a row into the SQL database. -func (d *Datastore) Put(ctx context.Context, key ds.Key, value []byte) error { - _, err := d.db.ExecContext(ctx, d.queries.Put(), key.String(), value) - if err != nil { - return err - } - - return nil -} - -// Query returns multiple rows from the SQL database based on the passed query parameters. -func (d *Datastore) Query(ctx context.Context, q dsq.Query) (dsq.Results, error) { - raw, err := d.rawQuery(ctx, q) - if err != nil { - return nil, err - } - - for _, f := range q.Filters { - raw = dsq.NaiveFilter(raw, f) - } - - raw = dsq.NaiveOrder(raw, q.Orders...) - - // if we have filters or orders, offset and limit won't have been applied in the query - if len(q.Filters) > 0 || len(q.Orders) > 0 { - if q.Offset != 0 { - raw = dsq.NaiveOffset(raw, q.Offset) - } - if q.Limit != 0 { - raw = dsq.NaiveLimit(raw, q.Limit) - } - } - - return raw, nil -} - -func (d *Datastore) rawQuery(ctx context.Context, q dsq.Query) (dsq.Results, error) { - var rows *sql.Rows - var err error - - rows, err = queryWithParams(ctx, d, q) - if err != nil { - return nil, err - } - - it := dsq.Iterator{ - Next: func() (dsq.Result, bool) { - if !rows.Next() { - return dsq.Result{}, false - } - - var key string - var out []byte - - err := rows.Scan(&key, &out) - if err != nil { - return dsq.Result{Error: err}, false - } - - entry := dsq.Entry{Key: key} - - if !q.KeysOnly { - entry.Value = out - } - if q.ReturnsSizes { - entry.Size = len(out) - } - - return dsq.Result{Entry: entry}, true - }, - Close: func() error { - return rows.Close() - }, - } - - return dsq.ResultsFromIterator(q, it), nil -} - -// Sync is noop for SQL databases. -func (d *Datastore) Sync(ctx context.Context, key ds.Key) error { - return nil -} - -// GetSize determines the size in bytes of the value for a given key. -func (d *Datastore) GetSize(ctx context.Context, key ds.Key) (int, error) { - row := d.db.QueryRowContext(ctx, d.queries.GetSize(), key.String()) - var size int - - switch err := row.Scan(&size); err { - case sql.ErrNoRows: - return -1, ds.ErrNotFound - case nil: - return size, nil - default: - return 0, err - } -} - -// queryWithParams applies prefix, limit, and offset params in pg query -func queryWithParams(ctx context.Context, d *Datastore, q dsq.Query) (*sql.Rows, error) { - var qNew = d.queries.Query() - - if q.Prefix != "" { - // normalize - prefix := ds.NewKey(q.Prefix).String() - if prefix != "/" { - qNew += fmt.Sprintf(d.queries.Prefix(), prefix+"/") - } - } - - // only apply limit and offset if we do not have to naive filter/order the results - if len(q.Filters) == 0 && len(q.Orders) == 0 { - if q.Limit != 0 { - qNew += fmt.Sprintf(d.queries.Limit(), q.Limit) - } - if q.Offset != 0 { - qNew += fmt.Sprintf(d.queries.Offset(), q.Offset) - } - } - - return d.db.QueryContext(ctx, qNew) - -} - -var _ ds.Datastore = (*Datastore)(nil) diff --git a/vendor/github.com/ipfs/go-ds-sql/package.json b/vendor/github.com/ipfs/go-ds-sql/package.json deleted file mode 100644 index f5cccc1b6..000000000 --- a/vendor/github.com/ipfs/go-ds-sql/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "author": "whyrusleeping", - "bugs": { - "url": "https://github.com/whyrusleeping/sql-datastore" - }, - "gx": { - "dvcsimport": "github.com/whyrusleeping/sql-datastore" - }, - "gxDependencies": [ - { - "author": "magik6k", - "hash": "QmfJhaxwzBCorUmZNRmY87z4mD6roRrHFMqddhiS4D4XWr", - "name": "pq", - "version": "1.0.0" - }, - { - "author": "jbenet", - "hash": "QmPGYyi1DtuWyUkG3PtvLz1xb4ScjnUvwJMCoX3cxeyxNr", - "name": "go-datastore", - "version": "3.5.0" - } - ], - "gxVersion": "0.14.0", - "language": "go", - "license": "", - "name": "sql-datastore", - "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", - "version": "1.0.2" -} - diff --git a/vendor/github.com/ipfs/go-ds-sql/txn.go b/vendor/github.com/ipfs/go-ds-sql/txn.go deleted file mode 100644 index 26f58ee6e..000000000 --- a/vendor/github.com/ipfs/go-ds-sql/txn.go +++ /dev/null @@ -1,122 +0,0 @@ -package sqlds - -import ( - "context" - "database/sql" - "fmt" - - datastore "github.com/ipfs/go-datastore" - dsq "github.com/ipfs/go-datastore/query" -) - -// ErrNotImplemented is returned when the SQL datastore does not yet implement the function call. -var ErrNotImplemented = fmt.Errorf("not implemented") - -type txn struct { - db *sql.DB - queries Queries - txn *sql.Tx -} - -// NewTransaction creates a new database transaction, note the readOnly parameter is ignored by this implementation. -func (ds *Datastore) NewTransaction(ctx context.Context, _ bool) (datastore.Txn, error) { - sqlTxn, err := ds.db.BeginTx(ctx, nil) - if err != nil { - if sqlTxn != nil { - // nothing we can do about this error. - _ = sqlTxn.Rollback() - } - - return nil, err - } - - return &txn{ - db: ds.db, - queries: ds.queries, - txn: sqlTxn, - }, nil -} - -func (t *txn) Get(ctx context.Context, key datastore.Key) ([]byte, error) { - row := t.txn.QueryRowContext(ctx, t.queries.Get(), key.String()) - var out []byte - - switch err := row.Scan(&out); err { - case sql.ErrNoRows: - return nil, datastore.ErrNotFound - case nil: - return out, nil - default: - return nil, err - } -} - -func (t *txn) Has(ctx context.Context, key datastore.Key) (bool, error) { - row := t.txn.QueryRowContext(ctx, t.queries.Exists(), key.String()) - var exists bool - - switch err := row.Scan(&exists); err { - case sql.ErrNoRows: - return exists, nil - case nil: - return exists, nil - default: - return exists, err - } -} - -func (t *txn) GetSize(ctx context.Context, key datastore.Key) (int, error) { - row := t.txn.QueryRowContext(ctx, t.queries.GetSize(), key.String()) - var size int - - switch err := row.Scan(&size); err { - case sql.ErrNoRows: - return -1, datastore.ErrNotFound - case nil: - return size, nil - default: - return 0, err - } -} - -func (t *txn) Query(ctx context.Context, q dsq.Query) (dsq.Results, error) { - return nil, ErrNotImplemented -} - -// Put adds a value to the datastore identified by the given key. -func (t *txn) Put(ctx context.Context, key datastore.Key, val []byte) error { - _, err := t.txn.ExecContext(ctx, t.queries.Put(), key.String(), val) - if err != nil { - _ = t.txn.Rollback() - return err - } - return nil -} - -// Delete removes a value from the datastore that matches the given key. -func (t *txn) Delete(ctx context.Context, key datastore.Key) error { - _, err := t.txn.ExecContext(ctx, t.queries.Delete(), key.String()) - if err != nil { - _ = t.txn.Rollback() - return err - } - return nil -} - -// Commit finalizes a transaction. -func (t *txn) Commit(ctx context.Context) error { - err := t.txn.Commit() - if err != nil { - _ = t.txn.Rollback() - return err - } - return nil -} - -// Discard throws away changes recorded in a transaction without committing -// them to the underlying Datastore. -func (t *txn) Discard(ctx context.Context) { - _ = t.txn.Rollback() -} - -var _ datastore.TxnDatastore = (*Datastore)(nil) diff --git a/vendor/github.com/ipfs/go-ds-sql/version.json b/vendor/github.com/ipfs/go-ds-sql/version.json deleted file mode 100644 index 1b4dded5a..000000000 --- a/vendor/github.com/ipfs/go-ds-sql/version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "version": "v0.3.0" -} \ No newline at end of file diff --git a/vendor/github.com/jbenet/goprocess/.travis.yml b/vendor/github.com/jbenet/goprocess/.travis.yml deleted file mode 100644 index 77d0e7d7d..000000000 --- a/vendor/github.com/jbenet/goprocess/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -sudo: false - -language: go - -go: - - 1.12 - -script: - - go test -race -v ./... diff --git a/vendor/github.com/jbenet/goprocess/LICENSE b/vendor/github.com/jbenet/goprocess/LICENSE deleted file mode 100644 index c7386b3c9..000000000 --- a/vendor/github.com/jbenet/goprocess/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Juan Batiz-Benet - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/jbenet/goprocess/README.md b/vendor/github.com/jbenet/goprocess/README.md deleted file mode 100644 index e2f12e16d..000000000 --- a/vendor/github.com/jbenet/goprocess/README.md +++ /dev/null @@ -1,132 +0,0 @@ -# goprocess - lifecycles in go - -[![travisbadge](https://travis-ci.org/jbenet/goprocess.svg)](https://travis-ci.org/jbenet/goprocess) - -(Based on https://github.com/jbenet/go-ctxgroup) - -- Godoc: https://godoc.org/github.com/jbenet/goprocess - -`goprocess` introduces a way to manage process lifecycles in go. It is -much like [go.net/context](https://godoc.org/code.google.com/p/go.net/context) -(it actually uses a Context), but it is more like a Context-WaitGroup hybrid. -`goprocess` is about being able to start and stop units of work, which may -receive `Close` signals from many clients. Think of it like a UNIX process -tree, but inside go. - -`goprocess` seeks to minimally affect your objects, so you can use it -with both embedding or composition. At the heart of `goprocess` is the -`Process` interface: - -```Go -// Process is the basic unit of work in goprocess. It defines a computation -// with a lifecycle: -// - running (before calling Close), -// - closing (after calling Close at least once), -// - closed (after Close returns, and all teardown has _completed_). -// -// More specifically, it fits this: -// -// p := WithTeardown(tf) // new process is created, it is now running. -// p.AddChild(q) // can register children **before** Closing. -// go p.Close() // blocks until done running teardown func. -// <-p.Closing() // would now return true. -// <-p.childrenDone() // wait on all children to be done -// p.teardown() // runs the user's teardown function tf. -// p.Close() // now returns, with error teardown returned. -// <-p.Closed() // would now return true. -// -// Processes can be arranged in a process "tree", where children are -// automatically Closed if their parents are closed. (Note, it is actually -// a Process DAG, children may have multiple parents). A process may also -// optionally wait for another to fully Close before beginning to Close. -// This makes it easy to ensure order of operations and proper sequential -// teardown of resurces. For example: -// -// p1 := goprocess.WithTeardown(func() error { -// fmt.Println("closing 1") -// }) -// p2 := goprocess.WithTeardown(func() error { -// fmt.Println("closing 2") -// }) -// p3 := goprocess.WithTeardown(func() error { -// fmt.Println("closing 3") -// }) -// -// p1.AddChild(p2) -// p2.AddChild(p3) -// -// -// go p1.Close() -// go p2.Close() -// go p3.Close() -// -// // Output: -// // closing 3 -// // closing 2 -// // closing 1 -// -// Process is modelled after the UNIX processes group idea, and heavily -// informed by sync.WaitGroup and go.net/context.Context. -// -// In the function documentation of this interface, `p` always refers to -// the self Process. -type Process interface { - - // WaitFor makes p wait for q before exiting. Thus, p will _always_ close - // _after_ q. Note well: a waiting cycle is deadlock. - // - // If q is already Closed, WaitFor calls p.Close() - // If p is already Closing or Closed, WaitFor panics. This is the same thing - // as calling Add(1) _after_ calling Done() on a wait group. Calling WaitFor - // on an already-closed process is a programming error likely due to bad - // synchronization - WaitFor(q Process) - - // AddChildNoWait registers child as a "child" of Process. As in UNIX, - // when parent is Closed, child is Closed -- child may Close beforehand. - // This is the equivalent of calling: - // - // go func(parent, child Process) { - // <-parent.Closing() - // child.Close() - // }(p, q) - // - // Note: the naming of functions is `AddChildNoWait` and `AddChild` (instead - // of `AddChild` and `AddChildWaitFor`) because: - // - it is the more common operation, - // - explicitness is helpful in the less common case (no waiting), and - // - usual "child" semantics imply parent Processes should wait for children. - AddChildNoWait(q Process) - - // AddChild is the equivalent of calling: - // parent.AddChildNoWait(q) - // parent.WaitFor(q) - AddChild(q Process) - - // Go creates a new process, adds it as a child, and spawns the ProcessFunc f - // in its own goroutine. It is equivalent to: - // - // GoChild(p, f) - // - // It is useful to construct simple asynchronous workers, children of p. - Go(f ProcessFunc) Process - - // Close ends the process. Close blocks until the process has completely - // shut down, and any teardown has run _exactly once_. The returned error - // is available indefinitely: calling Close twice returns the same error. - // If the process has already been closed, Close returns immediately. - Close() error - - // Closing is a signal to wait upon. The returned channel is closed - // _after_ Close has been called at least once, but teardown may or may - // not be done yet. The primary use case of Closing is for children who - // need to know when a parent is shutting down, and therefore also shut - // down. - Closing() <-chan struct{} - - // Closed is a signal to wait upon. The returned channel is closed - // _after_ Close has completed; teardown has finished. The primary use case - // of Closed is waiting for a Process to Close without _causing_ the Close. - Closed() <-chan struct{} -} -``` diff --git a/vendor/github.com/jbenet/goprocess/background.go b/vendor/github.com/jbenet/goprocess/background.go deleted file mode 100644 index d65815708..000000000 --- a/vendor/github.com/jbenet/goprocess/background.go +++ /dev/null @@ -1,33 +0,0 @@ -package goprocess - -// Background returns the "bgProcess" Process: a statically allocated -// process that can _never_ close. It also never enters Closing() state. -// Calling Background().Close() will hang indefinitely. -func Background() Process { - return background -} - -var background = new(bgProcess) - -type bgProcess struct{} - -func (*bgProcess) WaitFor(q Process) {} -func (*bgProcess) AddChildNoWait(q Process) {} -func (*bgProcess) AddChild(q Process) {} -func (*bgProcess) Close() error { select {} } -func (*bgProcess) CloseAfterChildren() error { select {} } -func (*bgProcess) Closing() <-chan struct{} { return nil } -func (*bgProcess) Closed() <-chan struct{} { return nil } -func (*bgProcess) Err() error { select {} } - -func (*bgProcess) SetTeardown(tf TeardownFunc) { - panic("can't set teardown on bgProcess process") -} -func (*bgProcess) Go(f ProcessFunc) Process { - child := newProcess(nil) - go func() { - f(child) - child.Close() - }() - return child -} diff --git a/vendor/github.com/jbenet/goprocess/goprocess.go b/vendor/github.com/jbenet/goprocess/goprocess.go deleted file mode 100644 index 48b76e2ea..000000000 --- a/vendor/github.com/jbenet/goprocess/goprocess.go +++ /dev/null @@ -1,263 +0,0 @@ -// Package goprocess introduces a Process abstraction that allows simple -// organization, and orchestration of work. It is much like a WaitGroup, -// and much like a context.Context, but also ensures safe **exactly-once**, -// and well-ordered teardown semantics. -package goprocess - -import ( - "os" - "os/signal" -) - -// Process is the basic unit of work in goprocess. It defines a computation -// with a lifecycle: -// - running (before calling Close), -// - closing (after calling Close at least once), -// - closed (after Close returns, and all teardown has _completed_). -// -// More specifically, it fits this: -// -// p := WithTeardown(tf) // new process is created, it is now running. -// p.AddChild(q) // can register children **before** Closed(). -// go p.Close() // blocks until done running teardown func. -// <-p.Closing() // would now return true. -// <-p.childrenDone() // wait on all children to be done -// p.teardown() // runs the user's teardown function tf. -// p.Close() // now returns, with error teardown returned. -// <-p.Closed() // would now return true. -// -// Processes can be arranged in a process "tree", where children are -// automatically Closed if their parents are closed. (Note, it is actually -// a Process DAG, children may have multiple parents). A process may also -// optionally wait for another to fully Close before beginning to Close. -// This makes it easy to ensure order of operations and proper sequential -// teardown of resurces. For example: -// -// p1 := goprocess.WithTeardown(func() error { -// fmt.Println("closing 1") -// }) -// p2 := goprocess.WithTeardown(func() error { -// fmt.Println("closing 2") -// }) -// p3 := goprocess.WithTeardown(func() error { -// fmt.Println("closing 3") -// }) -// -// p1.AddChild(p2) -// p2.AddChild(p3) -// -// -// go p1.Close() -// go p2.Close() -// go p3.Close() -// -// // Output: -// // closing 3 -// // closing 2 -// // closing 1 -// -// Process is modelled after the UNIX processes group idea, and heavily -// informed by sync.WaitGroup and go.net/context.Context. -// -// In the function documentation of this interface, `p` always refers to -// the self Process. -type Process interface { - - // WaitFor makes p wait for q before exiting. Thus, p will _always_ close - // _after_ q. Note well: a waiting cycle is deadlock. - // - // If p is already Closed, WaitFor panics. This is the same thing as - // calling Add(1) _after_ calling Done() on a wait group. Calling - // WaitFor on an already-closed process is a programming error likely - // due to bad synchronization - WaitFor(q Process) - - // AddChildNoWait registers child as a "child" of Process. As in UNIX, - // when parent is Closed, child is Closed -- child may Close beforehand. - // This is the equivalent of calling: - // - // go func(parent, child Process) { - // <-parent.Closing() - // child.Close() - // }(p, q) - // - // Note: the naming of functions is `AddChildNoWait` and `AddChild` (instead - // of `AddChild` and `AddChildWaitFor`) because: - // - it is the more common operation, - // - explicitness is helpful in the less common case (no waiting), and - // - usual "child" semantics imply parent Processes should wait for children. - AddChildNoWait(q Process) - - // AddChild is the equivalent of calling: - // parent.AddChildNoWait(q) - // parent.WaitFor(q) - // - // It will _panic_ if the parent is already closed. - AddChild(q Process) - - // Go is much like `go`, as it runs a function in a newly spawned goroutine. - // The neat part of Process.Go is that the Process object you call it on will: - // * construct a child Process, and call AddChild(child) on it - // * spawn a goroutine, and call the given function - // * Close the child when the function exits. - // This way, you can rest assured each goroutine you spawn has its very own - // Process context, and that it will be closed when the function exits. - // It is the function's responsibility to respect the Closing of its Process, - // namely it should exit (return) when <-Closing() is ready. It is basically: - // - // func (p Process) Go(f ProcessFunc) Process { - // child := WithParent(p) - // go func () { - // f(child) - // child.Close() - // }() - // } - // - // It is useful to construct simple asynchronous workers, children of p. - Go(f ProcessFunc) Process - - // SetTeardown sets the process's teardown to tf. - SetTeardown(tf TeardownFunc) - - // Close ends the process. Close blocks until the process has completely - // shut down, and any teardown has run _exactly once_. The returned error - // is available indefinitely: calling Close twice returns the same error. - // If the process has already been closed, Close returns immediately. - Close() error - - // CloseAfterChildren calls Close _after_ its children have Closed - // normally (i.e. it _does not_ attempt to close them). - CloseAfterChildren() error - - // Closing is a signal to wait upon. The returned channel is closed - // _after_ Close has been called at least once, but teardown may or may - // not be done yet. The primary use case of Closing is for children who - // need to know when a parent is shutting down, and therefore also shut - // down. - Closing() <-chan struct{} - - // Closed is a signal to wait upon. The returned channel is closed - // _after_ Close has completed; teardown has finished. The primary use case - // of Closed is waiting for a Process to Close without _causing_ the Close. - Closed() <-chan struct{} - - // Err waits until the process is closed, and then returns any error that - // occurred during shutdown. - Err() error -} - -// TeardownFunc is a function used to cleanup state at the end of the -// lifecycle of a Process. -type TeardownFunc func() error - -// ProcessFunc is a function that takes a process. Its main use case is goprocess.Go, -// which spawns a ProcessFunc in its own goroutine, and returns a corresponding -// Process object. -type ProcessFunc func(proc Process) - -var nilProcessFunc = func(Process) {} - -// Go is much like `go`: it runs a function in a newly spawned goroutine. The neat -// part of Go is that it provides Process object to communicate between the -// function and the outside world. Thus, callers can easily WaitFor, or Close the -// function. It is the function's responsibility to respect the Closing of its Process, -// namely it should exit (return) when <-Closing() is ready. It is simply: -// -// func Go(f ProcessFunc) Process { -// p := WithParent(Background()) -// p.Go(f) -// return p -// } -// -// Note that a naive implementation of Go like the following would not work: -// -// func Go(f ProcessFunc) Process { -// return Background().Go(f) -// } -// -// This is because having the process you -func Go(f ProcessFunc) Process { - // return GoChild(Background(), f) - - // we use two processes, one for communication, and - // one for ensuring we wait on the function (unclosable from the outside). - p := newProcess(nil) - waitFor := newProcess(nil) - p.WaitFor(waitFor) // prevent p from closing - go func() { - f(p) - waitFor.Close() // allow p to close. - p.Close() // ensure p closes. - }() - return p -} - -// GoChild is like Go, but it registers the returned Process as a child of parent, -// **before** spawning the goroutine, which ensures proper synchronization with parent. -// It is somewhat like -// -// func GoChild(parent Process, f ProcessFunc) Process { -// p := WithParent(parent) -// p.Go(f) -// return p -// } -// -// And it is similar to the classic WaitGroup use case: -// -// func WaitGroupGo(wg sync.WaitGroup, child func()) { -// wg.Add(1) -// go func() { -// child() -// wg.Done() -// }() -// } -// -func GoChild(parent Process, f ProcessFunc) Process { - p := WithParent(parent) - p.Go(f) - return p -} - -// Spawn is an alias of `Go`. In many contexts, Spawn is a -// well-known Process launching word, which fits our use case. -var Spawn = Go - -// SpawnChild is an alias of `GoChild`. In many contexts, Spawn is a -// well-known Process launching word, which fits our use case. -var SpawnChild = GoChild - -// WithTeardown constructs and returns a Process with a TeardownFunc. -// TeardownFunc tf will be called **exactly-once** when Process is -// Closing, after all Children have fully closed, and before p is Closed. -// In fact, Process p will not be Closed until tf runs and exits. -// See lifecycle in Process doc. -func WithTeardown(tf TeardownFunc) Process { - if tf == nil { - panic("nil tf TeardownFunc") - } - return newProcess(tf) -} - -// WithParent constructs and returns a Process with a given parent. -func WithParent(parent Process) Process { - if parent == nil { - panic("nil parent Process") - } - q := newProcess(nil) - parent.AddChild(q) - return q -} - -// WithSignals returns a Process that will Close() when any given signal fires. -// This is useful to bind Process trees to syscall.SIGTERM, SIGKILL, etc. -func WithSignals(sig ...os.Signal) Process { - p := WithParent(Background()) - c := make(chan os.Signal, 1) - signal.Notify(c, sig...) - go func() { - <-c - signal.Stop(c) - p.Close() - }() - return p -} diff --git a/vendor/github.com/jbenet/goprocess/impl-mutex.go b/vendor/github.com/jbenet/goprocess/impl-mutex.go deleted file mode 100644 index 535e609ac..000000000 --- a/vendor/github.com/jbenet/goprocess/impl-mutex.go +++ /dev/null @@ -1,299 +0,0 @@ -package goprocess - -import ( - "sync" -) - -// process implements Process -type process struct { - children map[*processLink]struct{} // process to close with us - waitfors map[*processLink]struct{} // process to only wait for - waiters []*processLink // processes that wait for us. for gc. - - teardown TeardownFunc // called to run the teardown logic. - closing chan struct{} // closed once close starts. - closed chan struct{} // closed once close is done. - closeErr error // error to return to clients of Close() - - sync.Mutex -} - -// newProcess constructs and returns a Process. -// It will call tf TeardownFunc exactly once: -// **after** all children have fully Closed, -// **after** entering <-Closing(), and -// **before** <-Closed(). -func newProcess(tf TeardownFunc) *process { - return &process{ - teardown: tf, - closed: make(chan struct{}), - closing: make(chan struct{}), - waitfors: make(map[*processLink]struct{}), - children: make(map[*processLink]struct{}), - } -} - -func (p *process) WaitFor(q Process) { - if q == nil { - panic("waiting for nil process") - } - - p.Lock() - defer p.Unlock() - - select { - case <-p.Closed(): - panic("Process cannot wait after being closed") - default: - } - - pl := newProcessLink(p, q) - if p.waitfors == nil { - // This may be nil when we're closing. In close, we'll keep - // reading this map till it stays nil. - p.waitfors = make(map[*processLink]struct{}, 1) - } - p.waitfors[pl] = struct{}{} - go pl.AddToChild() -} - -func (p *process) AddChildNoWait(child Process) { - if child == nil { - panic("adding nil child process") - } - - p.Lock() - defer p.Unlock() - - select { - case <-p.Closing(): - // Either closed or closing, close child immediately. This is - // correct because we aren't asked to _wait_ on this child. - go child.Close() - // Wait for the child to start closing so the child is in the - // "correct" state after this function finishes (see #17). - <-child.Closing() - return - default: - } - - pl := newProcessLink(p, child) - p.children[pl] = struct{}{} - go pl.AddToChild() -} - -func (p *process) AddChild(child Process) { - if child == nil { - panic("adding nil child process") - } - - p.Lock() - defer p.Unlock() - - pl := newProcessLink(p, child) - - select { - case <-p.Closed(): - // AddChild must not be called on a dead process. Maybe that's - // too strict? - panic("Process cannot add children after being closed") - default: - } - - select { - case <-p.Closing(): - // Already closing, close child in background. - go child.Close() - // Wait for the child to start closing so the child is in the - // "correct" state after this function finishes (see #17). - <-child.Closing() - default: - // Only add the child when not closing. When closing, just add - // it to the "waitfors" list. - p.children[pl] = struct{}{} - } - - if p.waitfors == nil { - // This may be be nil when we're closing. In close, we'll keep - // reading this map till it stays nil. - p.waitfors = make(map[*processLink]struct{}, 1) - } - p.waitfors[pl] = struct{}{} - go pl.AddToChild() -} - -func (p *process) Go(f ProcessFunc) Process { - child := newProcess(nil) - waitFor := newProcess(nil) - child.WaitFor(waitFor) // prevent child from closing - - // add child last, to prevent a closing parent from - // closing all of them prematurely, before running the func. - p.AddChild(child) - go func() { - f(child) - waitFor.Close() // allow child to close. - child.CloseAfterChildren() // close to tear down. - }() - return child -} - -// SetTeardown to assign a teardown function -func (p *process) SetTeardown(tf TeardownFunc) { - if tf == nil { - panic("cannot set nil TeardownFunc") - } - - p.Lock() - if p.teardown != nil { - panic("cannot SetTeardown twice") - } - - p.teardown = tf - select { - case <-p.Closed(): - // Call the teardown function, but don't set the error. We can't - // change that after we shut down. - tf() - default: - } - p.Unlock() -} - -// Close is the external close function. -// it's a wrapper around internalClose that waits on Closed() -func (p *process) Close() error { - p.Lock() - - // if already closing, or closed, get out. (but wait!) - select { - case <-p.Closing(): - p.Unlock() - <-p.Closed() - return p.closeErr - default: - } - - p.doClose() - p.Unlock() - return p.closeErr -} - -func (p *process) Closing() <-chan struct{} { - return p.closing -} - -func (p *process) Closed() <-chan struct{} { - return p.closed -} - -func (p *process) Err() error { - <-p.Closed() - return p.closeErr -} - -// the _actual_ close process. -func (p *process) doClose() { - // this function is only be called once (protected by p.Lock()). - // and it will panic (on closing channels) otherwise. - - close(p.closing) // signal that we're shutting down (Closing) - - // We won't add any children after we start closing so we can do this - // once. - for plc, _ := range p.children { - child := plc.Child() - if child != nil { // check because child may already have been removed. - go child.Close() // force all children to shut down - } - - // safe to call multiple times per link - plc.ParentClear() - } - p.children = nil // clear them. release memory. - - // We may repeatedly continue to add waiters while we wait to close so - // we have to do this in a loop. - for len(p.waitfors) > 0 { - // we must be careful not to iterate over waitfors directly, as it may - // change under our feet. - wf := p.waitfors - p.waitfors = nil // clear them. release memory. - for w, _ := range wf { - // Here, we wait UNLOCKED, so that waitfors who are in the middle of - // adding a child to us can finish. we will immediately close the child. - p.Unlock() - <-w.ChildClosed() // wait till all waitfors are fully closed (before teardown) - p.Lock() - - // safe to call multiple times per link - w.ParentClear() - } - } - - if p.teardown != nil { - p.closeErr = p.teardown() // actually run the close logic (ok safe to teardown) - } - close(p.closed) // signal that we're shut down (Closed) - - // go remove all the parents from the process links. optimization. - go func(waiters []*processLink) { - for _, pl := range waiters { - pl.ClearChild() - pr, ok := pl.Parent().(*process) - if !ok { - // parent has already been called to close - continue - } - pr.Lock() - delete(pr.waitfors, pl) - delete(pr.children, pl) - pr.Unlock() - } - }(p.waiters) // pass in so - p.waiters = nil // clear them. release memory. -} - -// We will only wait on the children we have now. -// We will not wait on children added subsequently. -// this may change in the future. -func (p *process) CloseAfterChildren() error { - p.Lock() - select { - case <-p.Closed(): - p.Unlock() - return p.Close() // get error. safe, after p.Closed() - default: - } - p.Unlock() - - // here only from one goroutine. - - nextToWaitFor := func() Process { - p.Lock() - defer p.Unlock() - for e, _ := range p.waitfors { - c := e.Child() - if c == nil { - continue - } - - select { - case <-c.Closed(): - default: - return c - } - } - return nil - } - - // wait for all processes we're waiting for are closed. - // the semantics here are simple: we will _only_ close - // if there are no processes currently waiting for. - for next := nextToWaitFor(); next != nil; next = nextToWaitFor() { - <-next.Closed() - } - - // YAY! we're done. close - return p.Close() -} diff --git a/vendor/github.com/jbenet/goprocess/link.go b/vendor/github.com/jbenet/goprocess/link.go deleted file mode 100644 index f46d81f68..000000000 --- a/vendor/github.com/jbenet/goprocess/link.go +++ /dev/null @@ -1,128 +0,0 @@ -package goprocess - -import ( - "sync" -) - -// closedCh is an alread-closed channel. used to return -// in cases where we already know a channel is closed. -var closedCh chan struct{} - -func init() { - closedCh = make(chan struct{}) - close(closedCh) -} - -// a processLink is an internal bookkeeping datastructure. -// it's used to form a relationship between two processes. -// It is mostly for keeping memory usage down (letting -// children close and be garbage-collected). -type processLink struct { - // guards all fields. - // DO NOT HOLD while holding process locks. - // it may be slow, and could deadlock if not careful. - sync.Mutex - parent Process - child Process -} - -func newProcessLink(p, c Process) *processLink { - return &processLink{ - parent: p, - child: c, - } -} - -// Closing returns whether the child is closing -func (pl *processLink) ChildClosing() <-chan struct{} { - // grab a hold of it, and unlock, as .Closing may block. - pl.Lock() - child := pl.child - pl.Unlock() - - if child == nil { // already closed? memory optimization. - return closedCh - } - return child.Closing() -} - -func (pl *processLink) ChildClosed() <-chan struct{} { - // grab a hold of it, and unlock, as .Closed may block. - pl.Lock() - child := pl.child - pl.Unlock() - - if child == nil { // already closed? memory optimization. - return closedCh - } - return child.Closed() -} - -func (pl *processLink) ChildClose() { - // grab a hold of it, and unlock, as .Closed may block. - pl.Lock() - child := pl.child - pl.Unlock() - - if child != nil { // already closed? memory optimization. - child.Close() - } -} - -func (pl *processLink) ClearChild() { - pl.Lock() - pl.child = nil - pl.Unlock() -} - -func (pl *processLink) ParentClear() { - pl.Lock() - pl.parent = nil - pl.Unlock() -} - -func (pl *processLink) Child() Process { - pl.Lock() - defer pl.Unlock() - return pl.child -} - -func (pl *processLink) Parent() Process { - pl.Lock() - defer pl.Unlock() - return pl.parent -} - -func (pl *processLink) AddToChild() { - cp := pl.Child() - - // is it a *process ? if not... panic. - var c *process - switch cp := cp.(type) { - case *process: - c = cp - case *bgProcess: - // Background process never closes so we don't need to do - // anything. - return - default: - panic("goprocess does not yet support other process impls.") - } - - // first, is it Closed? - c.Lock() - select { - case <-c.Closed(): - c.Unlock() - - // already closed. must not add. - // we must clear it, though. do so without the lock. - pl.ClearChild() - return - - default: - // put the process link into q's waiters - c.waiters = append(c.waiters, pl) - c.Unlock() - } -} diff --git a/vendor/github.com/jbenet/goprocess/package.json b/vendor/github.com/jbenet/goprocess/package.json deleted file mode 100644 index 074853377..000000000 --- a/vendor/github.com/jbenet/goprocess/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "author": "whyrusleeping", - "bugs": { - "url": "https://github.com/jbenet/goprocess" - }, - "gx": { - "dvcsimport": "github.com/jbenet/goprocess" - }, - "gxVersion": "0.8.0", - "language": "go", - "license": "", - "name": "goprocess", - "version": "1.0.0" -} diff --git a/vendor/github.com/klauspost/compress/.gitignore b/vendor/github.com/klauspost/compress/.gitignore index b35f8449b..d31b37815 100644 --- a/vendor/github.com/klauspost/compress/.gitignore +++ b/vendor/github.com/klauspost/compress/.gitignore @@ -23,3 +23,10 @@ _testmain.go *.test *.prof /s2/cmd/_s2sx/sfx-exe + +# Linux perf files +perf.data +perf.data.old + +# gdb history +.gdb_history diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md index 0e2dc116a..2d6b01077 100644 --- a/vendor/github.com/klauspost/compress/README.md +++ b/vendor/github.com/klauspost/compress/README.md @@ -17,6 +17,78 @@ This package provides various compression algorithms. # changelog +* July 21, 2022 (v1.15.9) + + * zstd: Fix decoder crash on amd64 (no BMI) on invalid input https://github.com/klauspost/compress/pull/645 + * zstd: Disable decoder extended memory copies (amd64) due to possible crashes https://github.com/klauspost/compress/pull/644 + * zstd: Allow single segments up to "max decoded size" by @klauspost in https://github.com/klauspost/compress/pull/643 + +* July 13, 2022 (v1.15.8) + + * gzip: fix stack exhaustion bug in Reader.Read https://github.com/klauspost/compress/pull/641 + * s2: Add Index header trim/restore https://github.com/klauspost/compress/pull/638 + * zstd: Optimize seqdeq amd64 asm by @greatroar in https://github.com/klauspost/compress/pull/636 + * zstd: Improve decoder memcopy https://github.com/klauspost/compress/pull/637 + * huff0: Pass a single bitReader pointer to asm by @greatroar in https://github.com/klauspost/compress/pull/634 + * zstd: Branchless getBits for amd64 w/o BMI2 by @greatroar in https://github.com/klauspost/compress/pull/640 + * gzhttp: Remove header before writing https://github.com/klauspost/compress/pull/639 + +* June 29, 2022 (v1.15.7) + + * s2: Fix absolute forward seeks https://github.com/klauspost/compress/pull/633 + * zip: Merge upstream https://github.com/klauspost/compress/pull/631 + * zip: Re-add zip64 fix https://github.com/klauspost/compress/pull/624 + * zstd: translate fseDecoder.buildDtable into asm by @WojciechMula in https://github.com/klauspost/compress/pull/598 + * flate: Faster histograms https://github.com/klauspost/compress/pull/620 + * deflate: Use compound hcode https://github.com/klauspost/compress/pull/622 + +* June 3, 2022 (v1.15.6) + * s2: Improve coding for long, close matches https://github.com/klauspost/compress/pull/613 + * s2c: Add Snappy/S2 stream recompression https://github.com/klauspost/compress/pull/611 + * zstd: Always use configured block size https://github.com/klauspost/compress/pull/605 + * zstd: Fix incorrect hash table placement for dict encoding in default https://github.com/klauspost/compress/pull/606 + * zstd: Apply default config to ZipDecompressor without options https://github.com/klauspost/compress/pull/608 + * gzhttp: Exclude more common archive formats https://github.com/klauspost/compress/pull/612 + * s2: Add ReaderIgnoreCRC https://github.com/klauspost/compress/pull/609 + * s2: Remove sanity load on index creation https://github.com/klauspost/compress/pull/607 + * snappy: Use dedicated function for scoring https://github.com/klauspost/compress/pull/614 + * s2c+s2d: Use official snappy framed extension https://github.com/klauspost/compress/pull/610 + +* May 25, 2022 (v1.15.5) + * s2: Add concurrent stream decompression https://github.com/klauspost/compress/pull/602 + * s2: Fix final emit oob read crash on amd64 https://github.com/klauspost/compress/pull/601 + * huff0: asm implementation of Decompress1X by @WojciechMula https://github.com/klauspost/compress/pull/596 + * zstd: Use 1 less goroutine for stream decoding https://github.com/klauspost/compress/pull/588 + * zstd: Copy literal in 16 byte blocks when possible https://github.com/klauspost/compress/pull/592 + * zstd: Speed up when WithDecoderLowmem(false) https://github.com/klauspost/compress/pull/599 + * zstd: faster next state update in BMI2 version of decode by @WojciechMula in https://github.com/klauspost/compress/pull/593 + * huff0: Do not check max size when reading table. https://github.com/klauspost/compress/pull/586 + * flate: Inplace hashing for level 7-9 by @klauspost in https://github.com/klauspost/compress/pull/590 + + +* May 11, 2022 (v1.15.4) + * huff0: decompress directly into output by @WojciechMula in [#577](https://github.com/klauspost/compress/pull/577) + * inflate: Keep dict on stack [#581](https://github.com/klauspost/compress/pull/581) + * zstd: Faster decoding memcopy in asm [#583](https://github.com/klauspost/compress/pull/583) + * zstd: Fix ignored crc [#580](https://github.com/klauspost/compress/pull/580) + +* May 5, 2022 (v1.15.3) + * zstd: Allow to ignore checksum checking by @WojciechMula [#572](https://github.com/klauspost/compress/pull/572) + * s2: Fix incorrect seek for io.SeekEnd in [#575](https://github.com/klauspost/compress/pull/575) + +* Apr 26, 2022 (v1.15.2) + * zstd: Add x86-64 assembly for decompression on streams and blocks. Contributed by [@WojciechMula](https://github.com/WojciechMula). Typically 2x faster. [#528](https://github.com/klauspost/compress/pull/528) [#531](https://github.com/klauspost/compress/pull/531) [#545](https://github.com/klauspost/compress/pull/545) [#537](https://github.com/klauspost/compress/pull/537) + * zstd: Add options to ZipDecompressor and fixes [#539](https://github.com/klauspost/compress/pull/539) + * s2: Use sorted search for index [#555](https://github.com/klauspost/compress/pull/555) + * Minimum version is Go 1.16, added CI test on 1.18. + +* Mar 11, 2022 (v1.15.1) + * huff0: Add x86 assembly of Decode4X by @WojciechMula in [#512](https://github.com/klauspost/compress/pull/512) + * zstd: Reuse zip decoders in [#514](https://github.com/klauspost/compress/pull/514) + * zstd: Detect extra block data and report as corrupted in [#520](https://github.com/klauspost/compress/pull/520) + * zstd: Handle zero sized frame content size stricter in [#521](https://github.com/klauspost/compress/pull/521) + * zstd: Add stricter block size checks in [#523](https://github.com/klauspost/compress/pull/523) + * Mar 3, 2022 (v1.15.0) * zstd: Refactor decoder by @klauspost in [#498](https://github.com/klauspost/compress/pull/498) * zstd: Add stream encoding without goroutines by @klauspost in [#505](https://github.com/klauspost/compress/pull/505) @@ -60,6 +132,9 @@ While the release has been extensively tested, it is recommended to testing when * zstd: add arm64 xxhash assembly in [#464](https://github.com/klauspost/compress/pull/464) * Add garbled for binaries for s2 in [#445](https://github.com/klauspost/compress/pull/445) +
+ See changes to v1.13.x + * Aug 30, 2021 (v1.13.5) * gz/zlib/flate: Alias stdlib errors [#425](https://github.com/klauspost/compress/pull/425) * s2: Add block support to commandline tools [#413](https://github.com/klauspost/compress/pull/413) @@ -88,6 +163,8 @@ While the release has been extensively tested, it is recommended to testing when * Added [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp#gzip-handler) which allows wrapping HTTP servers and clients with GZIP compressors. * zstd: Detect short invalid signatures [#382](https://github.com/klauspost/compress/pull/382) * zstd: Spawn decoder goroutine only if needed. [#380](https://github.com/klauspost/compress/pull/380) +
+
See changes to v1.12.x diff --git a/vendor/github.com/klauspost/compress/huff0/autogen.go b/vendor/github.com/klauspost/compress/huff0/autogen.go deleted file mode 100644 index ff2c69d60..000000000 --- a/vendor/github.com/klauspost/compress/huff0/autogen.go +++ /dev/null @@ -1,5 +0,0 @@ -package huff0 - -//go:generate go run generate.go -//go:generate asmfmt -w decompress_amd64.s -//go:generate asmfmt -w decompress_8b_amd64.s diff --git a/vendor/github.com/klauspost/compress/huff0/bitreader.go b/vendor/github.com/klauspost/compress/huff0/bitreader.go index 451160edd..504a7be9d 100644 --- a/vendor/github.com/klauspost/compress/huff0/bitreader.go +++ b/vendor/github.com/klauspost/compress/huff0/bitreader.go @@ -165,11 +165,6 @@ func (b *bitReaderShifted) peekBitsFast(n uint8) uint16 { return uint16(b.value >> ((64 - n) & 63)) } -// peekTopBits(n) is equvialent to peekBitFast(64 - n) -func (b *bitReaderShifted) peekTopBits(n uint8) uint16 { - return uint16(b.value >> n) -} - func (b *bitReaderShifted) advance(n uint8) { b.bitsRead += n b.value <<= n & 63 @@ -220,11 +215,6 @@ func (b *bitReaderShifted) fill() { } } -// finished returns true if all bits have been read from the bit stream. -func (b *bitReaderShifted) finished() bool { - return b.off == 0 && b.bitsRead >= 64 -} - func (b *bitReaderShifted) remaining() uint { return b.off*8 + uint(64-b.bitsRead) } diff --git a/vendor/github.com/klauspost/compress/huff0/bitwriter.go b/vendor/github.com/klauspost/compress/huff0/bitwriter.go index 6bce4e87d..ec71f7a34 100644 --- a/vendor/github.com/klauspost/compress/huff0/bitwriter.go +++ b/vendor/github.com/klauspost/compress/huff0/bitwriter.go @@ -5,8 +5,6 @@ package huff0 -import "fmt" - // bitWriter will write bits. // First bit will be LSB of the first byte of output. type bitWriter struct { @@ -23,14 +21,6 @@ var bitMask16 = [32]uint16{ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF} /* up to 16 bits */ -// addBits16NC will add up to 16 bits. -// It will not check if there is space for them, -// so the caller must ensure that it has flushed recently. -func (b *bitWriter) addBits16NC(value uint16, bits uint8) { - b.bitContainer |= uint64(value&bitMask16[bits&31]) << (b.nBits & 63) - b.nBits += bits -} - // addBits16Clean will add up to 16 bits. value may not contain more set bits than indicated. // It will not check if there is space for them, so the caller must ensure that it has flushed recently. func (b *bitWriter) addBits16Clean(value uint16, bits uint8) { @@ -70,104 +60,6 @@ func (b *bitWriter) encTwoSymbols(ct cTable, av, bv byte) { b.nBits += encA.nBits + encB.nBits } -// addBits16ZeroNC will add up to 16 bits. -// It will not check if there is space for them, -// so the caller must ensure that it has flushed recently. -// This is fastest if bits can be zero. -func (b *bitWriter) addBits16ZeroNC(value uint16, bits uint8) { - if bits == 0 { - return - } - value <<= (16 - bits) & 15 - value >>= (16 - bits) & 15 - b.bitContainer |= uint64(value) << (b.nBits & 63) - b.nBits += bits -} - -// flush will flush all pending full bytes. -// There will be at least 56 bits available for writing when this has been called. -// Using flush32 is faster, but leaves less space for writing. -func (b *bitWriter) flush() { - v := b.nBits >> 3 - switch v { - case 0: - return - case 1: - b.out = append(b.out, - byte(b.bitContainer), - ) - b.bitContainer >>= 1 << 3 - case 2: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - ) - b.bitContainer >>= 2 << 3 - case 3: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - ) - b.bitContainer >>= 3 << 3 - case 4: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - ) - b.bitContainer >>= 4 << 3 - case 5: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - ) - b.bitContainer >>= 5 << 3 - case 6: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - ) - b.bitContainer >>= 6 << 3 - case 7: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - ) - b.bitContainer >>= 7 << 3 - case 8: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - byte(b.bitContainer>>56), - ) - b.bitContainer = 0 - b.nBits = 0 - return - default: - panic(fmt.Errorf("bits (%d) > 64", b.nBits)) - } - b.nBits &= 7 -} - // flush32 will flush out, so there are at least 32 bits available for writing. func (b *bitWriter) flush32() { if b.nBits < 32 { @@ -201,10 +93,3 @@ func (b *bitWriter) close() error { b.flushAlign() return nil } - -// reset and continue writing by appending to out. -func (b *bitWriter) reset(out []byte) { - b.bitContainer = 0 - b.nBits = 0 - b.out = out -} diff --git a/vendor/github.com/klauspost/compress/huff0/bytereader.go b/vendor/github.com/klauspost/compress/huff0/bytereader.go index 50bcdf6ea..4dcab8d23 100644 --- a/vendor/github.com/klauspost/compress/huff0/bytereader.go +++ b/vendor/github.com/klauspost/compress/huff0/bytereader.go @@ -20,11 +20,6 @@ func (b *byteReader) init(in []byte) { b.off = 0 } -// advance the stream b n bytes. -func (b *byteReader) advance(n uint) { - b.off += int(n) -} - // Int32 returns a little endian int32 starting at current offset. func (b byteReader) Int32() int32 { v3 := int32(b.b[b.off+3]) @@ -43,11 +38,6 @@ func (b byteReader) Uint32() uint32 { return (v3 << 24) | (v2 << 16) | (v1 << 8) | v0 } -// unread returns the unread portion of the input. -func (b byteReader) unread() []byte { - return b.b[b.off:] -} - // remain will return the number of bytes remaining. func (b byteReader) remain() int { return len(b.b) - b.off diff --git a/vendor/github.com/klauspost/compress/huff0/compress.go b/vendor/github.com/klauspost/compress/huff0/compress.go index bc95ac623..4d14542fa 100644 --- a/vendor/github.com/klauspost/compress/huff0/compress.go +++ b/vendor/github.com/klauspost/compress/huff0/compress.go @@ -404,6 +404,7 @@ func (s *Scratch) canUseTable(c cTable) bool { return true } +//lint:ignore U1000 used for debugging func (s *Scratch) validateTable(c cTable) bool { if len(c) < int(s.symbolLen) { return false diff --git a/vendor/github.com/klauspost/compress/huff0/decompress.go b/vendor/github.com/klauspost/compress/huff0/decompress.go index 04f652995..42a237eac 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress.go @@ -11,7 +11,6 @@ import ( type dTable struct { single []dEntrySingle - double []dEntryDouble } // single-symbols decoding @@ -19,13 +18,6 @@ type dEntrySingle struct { entry uint16 } -// double-symbols decoding -type dEntryDouble struct { - seq [4]byte - nBits uint8 - len uint8 -} - // Uses special code for all tables that are < 8 bits. const use8BitTables = true @@ -35,7 +27,7 @@ const use8BitTables = true // If no Scratch is provided a new one is allocated. // The returned Scratch can be used for encoding or decoding input using this table. func ReadTable(in []byte, s *Scratch) (s2 *Scratch, remain []byte, err error) { - s, err = s.prepare(in) + s, err = s.prepare(nil) if err != nil { return s, nil, err } @@ -236,108 +228,6 @@ func (d *Decoder) buffer() *[4][256]byte { return &[4][256]byte{} } -// Decompress1X will decompress a 1X encoded stream. -// The cap of the output buffer will be the maximum decompressed size. -// The length of the supplied input must match the end of a block exactly. -func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { - if len(d.dt.single) == 0 { - return nil, errors.New("no table loaded") - } - if use8BitTables && d.actualTableLog <= 8 { - return d.decompress1X8Bit(dst, src) - } - var br bitReaderShifted - err := br.init(src) - if err != nil { - return dst, err - } - maxDecodedSize := cap(dst) - dst = dst[:0] - - // Avoid bounds check by always having full sized table. - const tlSize = 1 << tableLogMax - const tlMask = tlSize - 1 - dt := d.dt.single[:tlSize] - - // Use temp table to avoid bound checks/append penalty. - bufs := d.buffer() - buf := &bufs[0] - var off uint8 - - for br.off >= 8 { - br.fillFast() - v := dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+0] = uint8(v.entry >> 8) - - v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+1] = uint8(v.entry >> 8) - - // Refill - br.fillFast() - - v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+2] = uint8(v.entry >> 8) - - v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] - br.advance(uint8(v.entry)) - buf[off+3] = uint8(v.entry >> 8) - - off += 4 - if off == 0 { - if len(dst)+256 > maxDecodedSize { - br.close() - d.bufs.Put(bufs) - return nil, ErrMaxDecodedSizeExceeded - } - dst = append(dst, buf[:]...) - } - } - - if len(dst)+int(off) > maxDecodedSize { - d.bufs.Put(bufs) - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - dst = append(dst, buf[:off]...) - - // br < 8, so uint8 is fine - bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead - for bitsLeft > 0 { - br.fill() - if false && br.bitsRead >= 32 { - if br.off >= 4 { - v := br.in[br.off-4:] - v = v[:4] - low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - br.value = (br.value << 32) | uint64(low) - br.bitsRead -= 32 - br.off -= 4 - } else { - for br.off > 0 { - br.value = (br.value << 8) | uint64(br.in[br.off-1]) - br.bitsRead -= 8 - br.off-- - } - } - } - if len(dst) >= maxDecodedSize { - d.bufs.Put(bufs) - br.close() - return nil, ErrMaxDecodedSizeExceeded - } - v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] - nBits := uint8(v.entry) - br.advance(nBits) - bitsLeft -= nBits - dst = append(dst, uint8(v.entry>>8)) - } - d.bufs.Put(bufs) - return dst, br.close() -} - // decompress1X8Bit will decompress a 1X encoded stream with tablelog <= 8. // The cap of the output buffer will be the maximum decompressed size. // The length of the supplied input must match the end of a block exactly. @@ -873,17 +763,20 @@ func (d *Decoder) decompress4X8bit(dst, src []byte) ([]byte, error) { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 1") } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { @@ -995,7 +888,6 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) { const shift = 56 const tlSize = 1 << 8 - const tlMask = tlSize - 1 single := d.dt.single[:tlSize] // Use temp table to avoid bound checks/append penalty. @@ -1108,17 +1000,22 @@ func (d *Decoder) decompress4X8bitExactly(dst, src []byte) ([]byte, error) { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 1") } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + // copy(out[dstEvery*3:], buf[3][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s deleted file mode 100644 index 0d6cb1a96..000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s +++ /dev/null @@ -1,488 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: - - // const stream = 0 - // br0.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read - MOVQ bitReaderShifted_value(br0), br_value - MOVQ bitReaderShifted_off(br0), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill0 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br0), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br0.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill0: - - // val0 := br0.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 0(buffer)(off*1) - - // SECOND PART: - // val2 := br0.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 0+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br0) - MOVQ br_value, bitReaderShifted_value(br0) - MOVQ br_offset, bitReaderShifted_off(br0) - - // const stream = 1 - // br1.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read - MOVQ bitReaderShifted_value(br1), br_value - MOVQ bitReaderShifted_off(br1), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill1 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br1), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br1.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill1: - - // val0 := br1.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 256(buffer)(off*1) - - // SECOND PART: - // val2 := br1.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 256+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br1) - MOVQ br_value, bitReaderShifted_value(br1) - MOVQ br_offset, bitReaderShifted_off(br1) - - // const stream = 2 - // br2.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read - MOVQ bitReaderShifted_value(br2), br_value - MOVQ bitReaderShifted_off(br2), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill2 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br2), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br2.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill2: - - // val0 := br2.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 512(buffer)(off*1) - - // SECOND PART: - // val2 := br2.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 512+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br2) - MOVQ br_value, bitReaderShifted_value(br2) - MOVQ br_offset, bitReaderShifted_off(br2) - - // const stream = 3 - // br3.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read - MOVQ bitReaderShifted_value(br3), br_value - MOVQ bitReaderShifted_off(br3), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill3 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br3), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br3.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - - // } -skip_fill3: - - // val0 := br3.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 768(buffer)(off*1) - - // SECOND PART: - // val2 := br3.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, 768+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br3) - MOVQ br_value, bitReaderShifted_value(br3) - MOVQ br_offset, bitReaderShifted_off(br3) - - ADDQ $4, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop - -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET - -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in b/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in deleted file mode 100644 index 6d477a2c1..000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_8b_amd64.s.in +++ /dev/null @@ -1,197 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_8b_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: -{{ define "decode_2_values_x86" }} - // const stream = {{ var "id" }} - // br{{ var "id"}}.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read - MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value - MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset - - // if b.bitsRead >= 32 { - CMPQ br_bits_read, $32 - JB skip_fill{{ var "id" }} - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br{{ var "id" }}), AX - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - - // b.value |= uint64(low) << (b.bitsRead & 63) - MOVQ br_bits_read, CX - SHLQ CL, AX - ORQ AX, br_value - - // exhausted = exhausted || (br{{ var "id"}}.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - // } -skip_fill{{ var "id" }}: - - // val0 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val1 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, {{ var "bufofs" }}(buffer)(off*1) - - // SECOND PART: - // val2 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v2 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - // val3 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - - // v3 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - MOVBQZX AL, CX - SHLQ CX, br_value // value <<= n - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off+2] = uint8(v2.entry >> 8) - // buf[stream][off+3] = uint8(v3.entry >> 8) - MOVW BX, {{ var "bufofs" }}+2(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }}) - MOVQ br_value, bitReaderShifted_value(br{{ var "id" }}) - MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }}) -{{ end }} - - {{ set "id" "0" }} - {{ set "ofs" "0" }} - {{ set "bufofs" "0" }} {{/* id * bufoff */}} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "1" }} - {{ set "ofs" "8" }} - {{ set "bufofs" "256" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "2" }} - {{ set "ofs" "16" }} - {{ set "bufofs" "512" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "3" }} - {{ set "ofs" "24" }} - {{ set "bufofs" "768" }} - {{ template "decode_2_values_x86" . }} - - ADDQ $4, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go index d47f6644f..ba7e8e6b0 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.go @@ -2,30 +2,42 @@ // +build amd64,!appengine,!noasm,gc // This file contains the specialisation of Decoder.Decompress4X -// that uses an asm implementation of its main loop. +// and Decoder.Decompress1X that use an asm implementation of thir main loops. package huff0 import ( "errors" "fmt" + + "github.com/klauspost/compress/internal/cpuinfo" ) // decompress4x_main_loop_x86 is an x86 assembler implementation // of Decompress4X when tablelog > 8. -// go:noescape -func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, - peekBits uint8, buf *byte, tbl *dEntrySingle) uint8 +// +//go:noescape +func decompress4x_main_loop_amd64(ctx *decompress4xContext) // decompress4x_8b_loop_x86 is an x86 assembler implementation // of Decompress4X when tablelog <= 8 which decodes 4 entries // per loop. -// go:noescape -func decompress4x_8b_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, - peekBits uint8, buf *byte, tbl *dEntrySingle) uint8 +// +//go:noescape +func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) // fallback8BitSize is the size where using Go version is faster. const fallback8BitSize = 800 +type decompress4xContext struct { + pbr *[4]bitReaderShifted + peekBits uint8 + out *byte + dstEvery int + tbl *dEntrySingle + decoded int + limit *byte +} + // Decompress4X will decompress a 4X encoded stream. // The length of the supplied input must match the end of a block exactly. // The *capacity* of the dst slice must match the destination size of @@ -42,6 +54,7 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { if cap(dst) < fallback8BitSize && use8BitTables { return d.decompress4X8bit(dst, src) } + var br [4]bitReaderShifted // Decode "jump table" start := 6 @@ -71,70 +84,25 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { const tlMask = tlSize - 1 single := d.dt.single[:tlSize] - // Use temp table to avoid bound checks/append penalty. - buf := d.buffer() - var off uint8 var decoded int - const debug = false - - // see: bitReaderShifted.peekBitsFast() - peekBits := uint8((64 - d.actualTableLog) & 63) - - // Decode 2 values from each decoder/loop. - const bufoff = 256 - for { - if br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4 { - break + if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) { + ctx := decompress4xContext{ + pbr: &br, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + out: &out[0], + dstEvery: dstEvery, + tbl: &single[0], + limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last. } - if use8BitTables { - off = decompress4x_8b_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0]) + decompress4x_8b_main_loop_amd64(&ctx) } else { - off = decompress4x_main_loop_x86(&br[0], &br[1], &br[2], &br[3], peekBits, &buf[0][0], &single[0]) - } - if debug { - fmt.Print("DEBUG: ") - fmt.Printf("off=%d,", off) - for i := 0; i < 4; i++ { - fmt.Printf(" br[%d]={bitsRead=%d, value=%x, off=%d}", - i, br[i].bitsRead, br[i].value, br[i].off) - } - fmt.Println("") + decompress4x_main_loop_amd64(&ctx) } - if off != 0 { - break - } - - if bufoff > dstEvery { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 1") - } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 - // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 2") - } - } - if off > 0 { - ioff := int(off) - if len(out) < dstEvery*3+ioff { - d.bufs.Put(buf) - return nil, errors.New("corruption detected: stream overrun 3") - } - copy(out, buf[0][:off]) - copy(out[dstEvery:], buf[1][:off]) - copy(out[dstEvery*2:], buf[2][:off]) - copy(out[dstEvery*3:], buf[3][:off]) - decoded += int(off) * 4 - out = out[off:] + decoded = ctx.decoded + out = out[decoded/4:] } // Decode remaining. @@ -150,7 +118,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { for bitsLeft > 0 { br.fill() if offset >= endsAt { - d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 4") } @@ -164,7 +131,6 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { offset++ } if offset != endsAt { - d.bufs.Put(buf) return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt) } decoded += offset - dstEvery*i @@ -173,9 +139,88 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { return nil, err } } - d.bufs.Put(buf) if dstSize != decoded { return nil, errors.New("corruption detected: short output block") } return dst, nil } + +// decompress4x_main_loop_x86 is an x86 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_amd64(ctx *decompress1xContext) + +// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation +// of Decompress1X when tablelog > 8. +// +//go:noescape +func decompress1x_main_loop_bmi2(ctx *decompress1xContext) + +type decompress1xContext struct { + pbr *bitReaderShifted + peekBits uint8 + out *byte + outCap int + tbl *dEntrySingle + decoded int +} + +// Error reported by asm implementations +const error_max_decoded_size_exeeded = -1 + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:maxDecodedSize] + + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + + if maxDecodedSize >= 4 { + ctx := decompress1xContext{ + pbr: &br, + out: &dst[0], + outCap: maxDecodedSize, + peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast() + tbl: &d.dt.single[0], + } + + if cpuinfo.HasBMI2() { + decompress1x_main_loop_bmi2(&ctx) + } else { + decompress1x_main_loop_amd64(&ctx) + } + if ctx.decoded == error_max_decoded_size_exeeded { + return nil, ErrMaxDecodedSizeExceeded + } + + dst = dst[:ctx.decoded] + } + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if len(dst) >= maxDecodedSize { + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + return dst, br.close() +} diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s index 2edad3ea5..8d2187a2c 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s +++ b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s @@ -1,506 +1,846 @@ -// +build !appengine -// +build gc -// +build !noasm +// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT. -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" +//go:build amd64 && !appengine && !noasm && gc -#ifdef GOAMD64_v4 -#ifndef GOAMD64_v3 -#define GOAMD64_v3 -#endif -#endif +// func decompress4x_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_main_loop_amd64(SB), $0-8 + XORQ DX, DX -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -// func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 + // Preload values + MOVQ ctx+0(FP), AX + MOVBQZX 8(AX), DI + MOVQ 16(AX), SI + MOVQ 48(AX), BX + MOVQ 24(AX), R9 + MOVQ 32(AX), R10 + MOVQ (AX), R11 + // Main loop main_loop: + MOVQ SI, R8 + CMPQ R8, BX + SETGE DL - // const stream = 0 - // br0.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br0), br_bits_read - MOVQ bitReaderShifted_value(br0), br_value - MOVQ bitReaderShifted_off(br0), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill0 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br0), AX + // br0.fillFast32() + MOVQ 32(R11), R12 + MOVBQZX 40(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill0 + MOVQ 24(R11), AX + SUBQ $0x20, R13 + SUBQ $0x04, AX + MOVQ (R11), R14 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(R14*1), R14 + MOVQ R13, CX + SHLQ CL, R14 + MOVQ AX, 24(R11) + ORQ R14, R12 // exhausted = exhausted || (br0.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill0: - // val0 := br0.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 + MOVW (R10)(R14*2), CX - // br0.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) + // br0.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br0.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ DI, CX + MOVQ R12, R14 + SHRQ CL, R14 // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R10)(R14*2), CX // br0.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 0(buffer)(off*1) + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (R8) - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br0) - MOVQ br_value, bitReaderShifted_value(br0) - MOVQ br_offset, bitReaderShifted_off(br0) + // update the bitreader structure + MOVQ R12, 32(R11) + MOVB R13, 40(R11) + ADDQ R9, R8 - // const stream = 1 - // br1.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br1), br_bits_read - MOVQ bitReaderShifted_value(br1), br_value - MOVQ bitReaderShifted_off(br1), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill1 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br1), AX + // br1.fillFast32() + MOVQ 80(R11), R12 + MOVBQZX 88(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill1 + MOVQ 72(R11), AX + SUBQ $0x20, R13 + SUBQ $0x04, AX + MOVQ 48(R11), R14 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(R14*1), R14 + MOVQ R13, CX + SHLQ CL, R14 + MOVQ AX, 72(R11) + ORQ R14, R12 // exhausted = exhausted || (br1.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill1: - // val0 := br1.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 + MOVW (R10)(R14*2), CX - // br1.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) + // br1.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br1.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ DI, CX + MOVQ R12, R14 + SHRQ CL, R14 // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R10)(R14*2), CX // br1.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 256(buffer)(off*1) + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (R8) - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br1) - MOVQ br_value, bitReaderShifted_value(br1) - MOVQ br_offset, bitReaderShifted_off(br1) + // update the bitreader structure + MOVQ R12, 80(R11) + MOVB R13, 88(R11) + ADDQ R9, R8 - // const stream = 2 - // br2.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br2), br_bits_read - MOVQ bitReaderShifted_value(br2), br_value - MOVQ bitReaderShifted_off(br2), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill2 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br2), AX + // br2.fillFast32() + MOVQ 128(R11), R12 + MOVBQZX 136(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill2 + MOVQ 120(R11), AX + SUBQ $0x20, R13 + SUBQ $0x04, AX + MOVQ 96(R11), R14 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(R14*1), R14 + MOVQ R13, CX + SHLQ CL, R14 + MOVQ AX, 120(R11) + ORQ R14, R12 // exhausted = exhausted || (br2.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill2: - // val0 := br2.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 + MOVW (R10)(R14*2), CX - // br2.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) + // br2.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br2.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ DI, CX + MOVQ R12, R14 + SHRQ CL, R14 // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R10)(R14*2), CX // br2.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 512(buffer)(off*1) + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (R8) - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br2) - MOVQ br_value, bitReaderShifted_value(br2) - MOVQ br_offset, bitReaderShifted_off(br2) + // update the bitreader structure + MOVQ R12, 128(R11) + MOVB R13, 136(R11) + ADDQ R9, R8 - // const stream = 3 - // br3.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br3), br_bits_read - MOVQ bitReaderShifted_value(br3), br_value - MOVQ bitReaderShifted_off(br3), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill3 - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br3), AX + // br3.fillFast32() + MOVQ 176(R11), R12 + MOVBQZX 184(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill3 + MOVQ 168(R11), AX + SUBQ $0x20, R13 + SUBQ $0x04, AX + MOVQ 144(R11), R14 // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) - -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX - -#endif - - ORQ AX, br_value + MOVL (AX)(R14*1), R14 + MOVQ R13, CX + SHLQ CL, R14 + MOVQ AX, 168(R11) + ORQ R14, R12 // exhausted = exhausted || (br3.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH + CMPQ AX, $0x04 + SETLT AL + ORB AL, DL - // } skip_fill3: - // val0 := br3.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 + MOVW (R10)(R14*2), CX - // br3.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) + // br3.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask - -#else // val1 := br3.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask - -#endif + MOVQ DI, CX + MOVQ R12, R14 + SHRQ CL, R14 // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 + MOVW (R10)(R14*2), CX // br3.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n - -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n - -#endif - - ADDQ CX, br_bits_read // bits_read += n + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, 768(buffer)(off*1) + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + MOVW AX, (R8) - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br3) - MOVQ br_value, bitReaderShifted_value(br3) - MOVQ br_offset, bitReaderShifted_off(br3) - - ADDQ $2, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop - -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) + // update the bitreader structure + MOVQ R12, 176(R11) + MOVB R13, 184(R11) + ADDQ $0x02, SI + TESTB DL, DL + JZ main_loop + MOVQ ctx+0(FP), AX + SUBQ 16(AX), SI + SHLQ $0x02, SI + MOVQ SI, 40(AX) RET -#undef off -#undef buffer -#undef table +// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext) +TEXT ·decompress4x_8b_main_loop_amd64(SB), $0-8 + XORQ DX, DX -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted + // Preload values + MOVQ ctx+0(FP), CX + MOVBQZX 8(CX), DI + MOVQ 16(CX), BX + MOVQ 48(CX), SI + MOVQ 24(CX), R9 + MOVQ 32(CX), R10 + MOVQ (CX), R11 -#undef br0 -#undef br1 -#undef br2 -#undef br3 + // Main loop +main_loop: + MOVQ BX, R8 + CMPQ R8, SI + SETGE DL + + // br0.fillFast32() + MOVQ 32(R11), R12 + MOVBQZX 40(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill0 + MOVQ 24(R11), R14 + SUBQ $0x20, R13 + SUBQ $0x04, R14 + MOVQ (R11), R15 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R14)(R15*1), R15 + MOVQ R13, CX + SHLQ CL, R15 + MOVQ R14, 24(R11) + ORQ R15, R12 + + // exhausted = exhausted || (br0.off < 4) + CMPQ R14, $0x04 + SETLT AL + ORB AL, DL + +skip_fill0: + // val0 := br0.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v0 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br0.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + + // val1 := br0.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v1 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br0.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // val2 := br0.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v2 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br0.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + + // val3 := br0.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v3 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br0.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (R8) + + // update the bitreader structure + MOVQ R12, 32(R11) + MOVB R13, 40(R11) + ADDQ R9, R8 + + // br1.fillFast32() + MOVQ 80(R11), R12 + MOVBQZX 88(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill1 + MOVQ 72(R11), R14 + SUBQ $0x20, R13 + SUBQ $0x04, R14 + MOVQ 48(R11), R15 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R14)(R15*1), R15 + MOVQ R13, CX + SHLQ CL, R15 + MOVQ R14, 72(R11) + ORQ R15, R12 + + // exhausted = exhausted || (br1.off < 4) + CMPQ R14, $0x04 + SETLT AL + ORB AL, DL + +skip_fill1: + // val0 := br1.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v0 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br1.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + + // val1 := br1.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v1 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br1.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // val2 := br1.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v2 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br1.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + + // val3 := br1.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v3 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br1.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (R8) + + // update the bitreader structure + MOVQ R12, 80(R11) + MOVB R13, 88(R11) + ADDQ R9, R8 + + // br2.fillFast32() + MOVQ 128(R11), R12 + MOVBQZX 136(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill2 + MOVQ 120(R11), R14 + SUBQ $0x20, R13 + SUBQ $0x04, R14 + MOVQ 96(R11), R15 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R14)(R15*1), R15 + MOVQ R13, CX + SHLQ CL, R15 + MOVQ R14, 120(R11) + ORQ R15, R12 + + // exhausted = exhausted || (br2.off < 4) + CMPQ R14, $0x04 + SETLT AL + ORB AL, DL + +skip_fill2: + // val0 := br2.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v0 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br2.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + + // val1 := br2.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v1 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br2.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // val2 := br2.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v2 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br2.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + + // val3 := br2.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v3 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br2.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (R8) + + // update the bitreader structure + MOVQ R12, 128(R11) + MOVB R13, 136(R11) + ADDQ R9, R8 + + // br3.fillFast32() + MOVQ 176(R11), R12 + MOVBQZX 184(R11), R13 + CMPQ R13, $0x20 + JBE skip_fill3 + MOVQ 168(R11), R14 + SUBQ $0x20, R13 + SUBQ $0x04, R14 + MOVQ 144(R11), R15 + + // b.value |= uint64(low) << (b.bitsRead & 63) + MOVL (R14)(R15*1), R15 + MOVQ R13, CX + SHLQ CL, R15 + MOVQ R14, 168(R11) + ORQ R15, R12 + + // exhausted = exhausted || (br3.off < 4) + CMPQ R14, $0x04 + SETLT AL + ORB AL, DL + +skip_fill3: + // val0 := br3.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v0 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br3.advance(uint8(v0.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + + // val1 := br3.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v1 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br3.advance(uint8(v1.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // val2 := br3.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v2 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br3.advance(uint8(v2.entry) + MOVB CH, AH + SHLQ CL, R12 + ADDB CL, R13 + + // val3 := br3.peekTopBits(peekBits) + MOVQ R12, R14 + MOVQ DI, CX + SHRQ CL, R14 + + // v3 := table[val0&mask] + MOVW (R10)(R14*2), CX + + // br3.advance(uint8(v3.entry) + MOVB CH, AL + SHLQ CL, R12 + ADDB CL, R13 + BSWAPL AX + + // these four writes get coalesced + // out[id * dstEvery + 0] = uint8(v0.entry >> 8) + // out[id * dstEvery + 1] = uint8(v1.entry >> 8) + // out[id * dstEvery + 3] = uint8(v2.entry >> 8) + // out[id * dstEvery + 4] = uint8(v3.entry >> 8) + MOVL AX, (R8) + + // update the bitreader structure + MOVQ R12, 176(R11) + MOVB R13, 184(R11) + ADDQ $0x04, BX + TESTB DL, DL + JZ main_loop + MOVQ ctx+0(FP), AX + SUBQ 16(AX), BX + SHLQ $0x02, BX + MOVQ BX, 40(AX) + RET + +// func decompress1x_main_loop_amd64(ctx *decompress1xContext) +TEXT ·decompress1x_main_loop_amd64(SB), $0-8 + MOVQ ctx+0(FP), CX + MOVQ 16(CX), DX + MOVQ 24(CX), BX + CMPQ BX, $0x04 + JB error_max_decoded_size_exeeded + LEAQ (DX)(BX*1), BX + MOVQ (CX), SI + MOVQ (SI), R8 + MOVQ 24(SI), R9 + MOVQ 32(SI), R10 + MOVBQZX 40(SI), R11 + MOVQ 32(CX), SI + MOVBQZX 8(CX), DI + JMP loop_condition + +main_loop: + // Check if we have room for 4 bytes in the output buffer + LEAQ 4(DX), CX + CMPQ CX, BX + JGE error_max_decoded_size_exeeded + + // Decode 4 values + CMPQ R11, $0x20 + JL bitReader_fillFast_1_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), R12 + MOVQ R11, CX + SHLQ CL, R12 + ORQ R12, R10 + +bitReader_fillFast_1_end: + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + BSWAPL AX + CMPQ R11, $0x20 + JL bitReader_fillFast_2_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), R12 + MOVQ R11, CX + SHLQ CL, R12 + ORQ R12, R10 + +bitReader_fillFast_2_end: + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + MOVQ DI, CX + MOVQ R10, R12 + SHRQ CL, R12 + MOVW (SI)(R12*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLQ CL, R10 + BSWAPL AX + + // Store the decoded values + MOVL AX, (DX) + ADDQ $0x04, DX + +loop_condition: + CMPQ R9, $0x08 + JGE main_loop + + // Update ctx structure + MOVQ ctx+0(FP), AX + SUBQ 16(AX), DX + MOVQ DX, 40(AX) + MOVQ (AX), AX + MOVQ R9, 24(AX) + MOVQ R10, 32(AX) + MOVB R11, 40(AX) + RET + + // Report error +error_max_decoded_size_exeeded: + MOVQ ctx+0(FP), AX + MOVQ $-1, CX + MOVQ CX, 40(AX) + RET + +// func decompress1x_main_loop_bmi2(ctx *decompress1xContext) +// Requires: BMI2 +TEXT ·decompress1x_main_loop_bmi2(SB), $0-8 + MOVQ ctx+0(FP), CX + MOVQ 16(CX), DX + MOVQ 24(CX), BX + CMPQ BX, $0x04 + JB error_max_decoded_size_exeeded + LEAQ (DX)(BX*1), BX + MOVQ (CX), SI + MOVQ (SI), R8 + MOVQ 24(SI), R9 + MOVQ 32(SI), R10 + MOVBQZX 40(SI), R11 + MOVQ 32(CX), SI + MOVBQZX 8(CX), DI + JMP loop_condition + +main_loop: + // Check if we have room for 4 bytes in the output buffer + LEAQ 4(DX), CX + CMPQ CX, BX + JGE error_max_decoded_size_exeeded + + // Decode 4 values + CMPQ R11, $0x20 + JL bitReader_fillFast_1_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), CX + SHLXQ R11, CX, CX + ORQ CX, R10 + +bitReader_fillFast_1_end: + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + BSWAPL AX + CMPQ R11, $0x20 + JL bitReader_fillFast_2_end + SUBQ $0x20, R11 + SUBQ $0x04, R9 + MOVL (R8)(R9*1), CX + SHLXQ R11, CX, CX + ORQ CX, R10 + +bitReader_fillFast_2_end: + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AH + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + SHRXQ DI, R10, CX + MOVW (SI)(CX*2), CX + MOVB CH, AL + MOVBQZX CL, CX + ADDQ CX, R11 + SHLXQ CX, R10, R10 + BSWAPL AX + + // Store the decoded values + MOVL AX, (DX) + ADDQ $0x04, DX + +loop_condition: + CMPQ R9, $0x08 + JGE main_loop + + // Update ctx structure + MOVQ ctx+0(FP), AX + SUBQ 16(AX), DX + MOVQ DX, 40(AX) + MOVQ (AX), AX + MOVQ R9, 24(AX) + MOVQ R10, 32(AX) + MOVB R11, 40(AX) + RET + + // Report error +error_max_decoded_size_exeeded: + MOVQ ctx+0(FP), AX + MOVQ $-1, CX + MOVQ CX, 40(AX) + RET diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in b/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in deleted file mode 100644 index 330d86ae1..000000000 --- a/vendor/github.com/klauspost/compress/huff0/decompress_amd64.s.in +++ /dev/null @@ -1,195 +0,0 @@ -// +build !appengine -// +build gc -// +build !noasm - -#include "textflag.h" -#include "funcdata.h" -#include "go_asm.h" - -#ifdef GOAMD64_v4 -#ifndef GOAMD64_v3 -#define GOAMD64_v3 -#endif -#endif - -#define bufoff 256 // see decompress.go, we're using [4][256]byte table - -//func decompress4x_main_loop_x86(pbr0, pbr1, pbr2, pbr3 *bitReaderShifted, -// peekBits uint8, buf *byte, tbl *dEntrySingle) (int, bool) -TEXT ·decompress4x_main_loop_x86(SB), NOSPLIT, $8 -#define off R8 -#define buffer DI -#define table SI - -#define br_bits_read R9 -#define br_value R10 -#define br_offset R11 -#define peek_bits R12 -#define exhausted DX - -#define br0 R13 -#define br1 R14 -#define br2 R15 -#define br3 BP - - MOVQ BP, 0(SP) - - XORQ exhausted, exhausted // exhausted = false - XORQ off, off // off = 0 - - MOVBQZX peekBits+32(FP), peek_bits - MOVQ buf+40(FP), buffer - MOVQ tbl+48(FP), table - - MOVQ pbr0+0(FP), br0 - MOVQ pbr1+8(FP), br1 - MOVQ pbr2+16(FP), br2 - MOVQ pbr3+24(FP), br3 - -main_loop: -{{ define "decode_2_values_x86" }} - // const stream = {{ var "id" }} - // br{{ var "id"}}.fillFast() - MOVBQZX bitReaderShifted_bitsRead(br{{ var "id" }}), br_bits_read - MOVQ bitReaderShifted_value(br{{ var "id" }}), br_value - MOVQ bitReaderShifted_off(br{{ var "id" }}), br_offset - - // We must have at least 2 * max tablelog left - CMPQ br_bits_read, $64-22 - JBE skip_fill{{ var "id" }} - - SUBQ $32, br_bits_read // b.bitsRead -= 32 - SUBQ $4, br_offset // b.off -= 4 - - // v := b.in[b.off-4 : b.off] - // v = v[:4] - // low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) - MOVQ bitReaderShifted_in(br{{ var "id" }}), AX - - // b.value |= uint64(low) << (b.bitsRead & 63) -#ifdef GOAMD64_v3 - SHLXQ br_bits_read, 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) << (b.bitsRead & 63) -#else - MOVL 0(br_offset)(AX*1), AX // AX = uint32(b.in[b.off:b.off+4]) - MOVQ br_bits_read, CX - SHLQ CL, AX -#endif - - ORQ AX, br_value - - // exhausted = exhausted || (br{{ var "id"}}.off < 4) - CMPQ br_offset, $4 - SETLT DL - ORB DL, DH - // } -skip_fill{{ var "id" }}: - - // val0 := br{{ var "id"}}.peekTopBits(peekBits) -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask -#else - MOVQ br_value, AX - MOVQ peek_bits, CX - SHRQ CL, AX // AX = (value >> peek_bits) & mask -#endif - - // v0 := table[val0&mask] - MOVW 0(table)(AX*2), AX // AX - v0 - - // br{{ var "id"}}.advance(uint8(v0.entry)) - MOVB AH, BL // BL = uint8(v0.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n -#endif - - ADDQ CX, br_bits_read // bits_read += n - - -#ifdef GOAMD64_v3 - SHRXQ peek_bits, br_value, AX // AX = (value >> peek_bits) & mask -#else - // val1 := br{{ var "id"}}.peekTopBits(peekBits) - MOVQ peek_bits, CX - MOVQ br_value, AX - SHRQ CL, AX // AX = (value >> peek_bits) & mask -#endif - - // v1 := table[val1&mask] - MOVW 0(table)(AX*2), AX // AX - v1 - - // br{{ var "id"}}.advance(uint8(v1.entry)) - MOVB AH, BH // BH = uint8(v1.entry >> 8) - -#ifdef GOAMD64_v3 - MOVBQZX AL, CX - SHLXQ AX, br_value, br_value // value <<= n -#else - MOVBQZX AL, CX - SHLQ CL, br_value // value <<= n -#endif - - ADDQ CX, br_bits_read // bits_read += n - - - // these two writes get coalesced - // buf[stream][off] = uint8(v0.entry >> 8) - // buf[stream][off+1] = uint8(v1.entry >> 8) - MOVW BX, {{ var "bufofs" }}(buffer)(off*1) - - // update the bitrader reader structure - MOVB br_bits_read, bitReaderShifted_bitsRead(br{{ var "id" }}) - MOVQ br_value, bitReaderShifted_value(br{{ var "id" }}) - MOVQ br_offset, bitReaderShifted_off(br{{ var "id" }}) -{{ end }} - - {{ set "id" "0" }} - {{ set "ofs" "0" }} - {{ set "bufofs" "0" }} {{/* id * bufoff */}} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "1" }} - {{ set "ofs" "8" }} - {{ set "bufofs" "256" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "2" }} - {{ set "ofs" "16" }} - {{ set "bufofs" "512" }} - {{ template "decode_2_values_x86" . }} - - {{ set "id" "3" }} - {{ set "ofs" "24" }} - {{ set "bufofs" "768" }} - {{ template "decode_2_values_x86" . }} - - ADDQ $2, off // off += 2 - - TESTB DH, DH // any br[i].ofs < 4? - JNZ end - - CMPQ off, $bufoff - JL main_loop -end: - MOVQ 0(SP), BP - - MOVB off, ret+56(FP) - RET -#undef off -#undef buffer -#undef table - -#undef br_bits_read -#undef br_value -#undef br_offset -#undef peek_bits -#undef exhausted - -#undef br0 -#undef br1 -#undef br2 -#undef br3 diff --git a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go index 126b4d68a..908c17de6 100644 --- a/vendor/github.com/klauspost/compress/huff0/decompress_generic.go +++ b/vendor/github.com/klauspost/compress/huff0/decompress_generic.go @@ -122,17 +122,21 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 1") } - copy(out, buf[0][:]) - copy(out[dstEvery:], buf[1][:]) - copy(out[dstEvery*2:], buf[2][:]) - copy(out[dstEvery*3:], buf[3][:]) - out = out[bufoff:] - decoded += bufoff * 4 // There must at least be 3 buffers left. - if len(out) < dstEvery*3 { + if len(out)-bufoff < dstEvery*3 { d.bufs.Put(buf) return nil, errors.New("corruption detected: stream overrun 2") } + //copy(out, buf[0][:]) + //copy(out[dstEvery:], buf[1][:]) + //copy(out[dstEvery*2:], buf[2][:]) + //copy(out[dstEvery*3:], buf[3][:]) + *(*[bufoff]byte)(out) = buf[0] + *(*[bufoff]byte)(out[dstEvery:]) = buf[1] + *(*[bufoff]byte)(out[dstEvery*2:]) = buf[2] + *(*[bufoff]byte)(out[dstEvery*3:]) = buf[3] + out = out[bufoff:] + decoded += bufoff * 4 } } if off > 0 { @@ -191,3 +195,105 @@ func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) { } return dst, nil } + +// Decompress1X will decompress a 1X encoded stream. +// The cap of the output buffer will be the maximum decompressed size. +// The length of the supplied input must match the end of a block exactly. +func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) { + if len(d.dt.single) == 0 { + return nil, errors.New("no table loaded") + } + if use8BitTables && d.actualTableLog <= 8 { + return d.decompress1X8Bit(dst, src) + } + var br bitReaderShifted + err := br.init(src) + if err != nil { + return dst, err + } + maxDecodedSize := cap(dst) + dst = dst[:0] + + // Avoid bounds check by always having full sized table. + const tlSize = 1 << tableLogMax + const tlMask = tlSize - 1 + dt := d.dt.single[:tlSize] + + // Use temp table to avoid bound checks/append penalty. + bufs := d.buffer() + buf := &bufs[0] + var off uint8 + + for br.off >= 8 { + br.fillFast() + v := dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+0] = uint8(v.entry >> 8) + + v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+1] = uint8(v.entry >> 8) + + // Refill + br.fillFast() + + v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+2] = uint8(v.entry >> 8) + + v = dt[br.peekBitsFast(d.actualTableLog)&tlMask] + br.advance(uint8(v.entry)) + buf[off+3] = uint8(v.entry >> 8) + + off += 4 + if off == 0 { + if len(dst)+256 > maxDecodedSize { + br.close() + d.bufs.Put(bufs) + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:]...) + } + } + + if len(dst)+int(off) > maxDecodedSize { + d.bufs.Put(bufs) + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + dst = append(dst, buf[:off]...) + + // br < 8, so uint8 is fine + bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead + for bitsLeft > 0 { + br.fill() + if false && br.bitsRead >= 32 { + if br.off >= 4 { + v := br.in[br.off-4:] + v = v[:4] + low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24) + br.value = (br.value << 32) | uint64(low) + br.bitsRead -= 32 + br.off -= 4 + } else { + for br.off > 0 { + br.value = (br.value << 8) | uint64(br.in[br.off-1]) + br.bitsRead -= 8 + br.off-- + } + } + } + if len(dst) >= maxDecodedSize { + d.bufs.Put(bufs) + br.close() + return nil, ErrMaxDecodedSizeExceeded + } + v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask] + nBits := uint8(v.entry) + br.advance(nBits) + bitsLeft -= nBits + dst = append(dst, uint8(v.entry>>8)) + } + d.bufs.Put(bufs) + return dst, br.close() +} diff --git a/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go new file mode 100644 index 000000000..3954c5121 --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo.go @@ -0,0 +1,34 @@ +// Package cpuinfo gives runtime info about the current CPU. +// +// This is a very limited module meant for use internally +// in this project. For more versatile solution check +// https://github.com/klauspost/cpuid. +package cpuinfo + +// HasBMI1 checks whether an x86 CPU supports the BMI1 extension. +func HasBMI1() bool { + return hasBMI1 +} + +// HasBMI2 checks whether an x86 CPU supports the BMI2 extension. +func HasBMI2() bool { + return hasBMI2 +} + +// DisableBMI2 will disable BMI2, for testing purposes. +// Call returned function to restore previous state. +func DisableBMI2() func() { + old := hasBMI2 + hasBMI2 = false + return func() { + hasBMI2 = old + } +} + +// HasBMI checks whether an x86 CPU supports both BMI1 and BMI2 extensions. +func HasBMI() bool { + return HasBMI1() && HasBMI2() +} + +var hasBMI1 bool +var hasBMI2 bool diff --git a/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go new file mode 100644 index 000000000..e802579c4 --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.go @@ -0,0 +1,11 @@ +//go:build amd64 && !appengine && !noasm && gc +// +build amd64,!appengine,!noasm,gc + +package cpuinfo + +// go:noescape +func x86extensions() (bmi1, bmi2 bool) + +func init() { + hasBMI1, hasBMI2 = x86extensions() +} diff --git a/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s new file mode 100644 index 000000000..4465fbe9e --- /dev/null +++ b/vendor/github.com/klauspost/compress/internal/cpuinfo/cpuinfo_amd64.s @@ -0,0 +1,36 @@ +// +build !appengine +// +build gc +// +build !noasm + +#include "textflag.h" +#include "funcdata.h" +#include "go_asm.h" + +TEXT ·x86extensions(SB), NOSPLIT, $0 + // 1. determine max EAX value + XORQ AX, AX + CPUID + + CMPQ AX, $7 + JB unsupported + + // 2. EAX = 7, ECX = 0 --- see Table 3-8 "Information Returned by CPUID Instruction" + MOVQ $7, AX + MOVQ $0, CX + CPUID + + BTQ $3, BX // bit 3 = BMI1 + SETCS AL + + BTQ $8, BX // bit 8 = BMI2 + SETCS AH + + MOVB AL, bmi1+0(FP) + MOVB AH, bmi2+1(FP) + RET + +unsupported: + XORQ AX, AX + MOVB AL, bmi1+0(FP) + MOVB AL, bmi2+1(FP) + RET diff --git a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go index 511bba65d..298c4f8e9 100644 --- a/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go +++ b/vendor/github.com/klauspost/compress/internal/snapref/encode_other.go @@ -18,6 +18,7 @@ func load64(b []byte, i int) uint64 { // emitLiteral writes a literal chunk and returns the number of bytes written. // // It assumes that: +// // dst is long enough to hold the encoded bytes // 1 <= len(lit) && len(lit) <= 65536 func emitLiteral(dst, lit []byte) int { @@ -42,6 +43,7 @@ func emitLiteral(dst, lit []byte) int { // emitCopy writes a copy chunk and returns the number of bytes written. // // It assumes that: +// // dst is long enough to hold the encoded bytes // 1 <= offset && offset <= 65535 // 4 <= length && length <= 65535 @@ -89,6 +91,7 @@ func emitCopy(dst []byte, offset, length int) int { // src[i:i+k-j] and src[j:k] have the same contents. // // It assumes that: +// // 0 <= i && i < j && j <= len(src) func extendMatch(src []byte, i, j int) int { for ; j < len(src) && src[i] == src[j]; i, j = i+1, j+1 { @@ -105,8 +108,9 @@ func hash(u, shift uint32) uint32 { // been written. // // It also assumes that: +// // len(dst) >= MaxEncodedLen(len(src)) && -// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize +// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize func encodeBlock(dst, src []byte) (d int) { // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. // The table element type is uint16, as s < sLimit and sLimit < len(src) diff --git a/vendor/github.com/klauspost/compress/zstd/README.md b/vendor/github.com/klauspost/compress/zstd/README.md index e3445ac19..65b38abed 100644 --- a/vendor/github.com/klauspost/compress/zstd/README.md +++ b/vendor/github.com/klauspost/compress/zstd/README.md @@ -12,6 +12,8 @@ The `zstd` package is provided as open source software using a Go standard licen Currently the package is heavily optimized for 64 bit processors and will be significantly slower on 32 bit processors. +For seekable zstd streams, see [this excellent package](https://github.com/SaveTheRbtz/zstd-seekable-format-go). + ## Installation Install using `go get -u github.com/klauspost/compress`. The package is located in `github.com/klauspost/compress/zstd`. @@ -386,47 +388,31 @@ In practice this means that concurrency is often limited to utilizing about 3 co ### Benchmarks -These are some examples of performance compared to [datadog cgo library](https://github.com/DataDog/zstd). - The first two are streaming decodes and the last are smaller inputs. - + +Running on AMD Ryzen 9 3950X 16-Core Processor. AMD64 assembly used. + ``` -BenchmarkDecoderSilesia-8 3 385000067 ns/op 550.51 MB/s 5498 B/op 8 allocs/op -BenchmarkDecoderSilesiaCgo-8 6 197666567 ns/op 1072.25 MB/s 270672 B/op 8 allocs/op +BenchmarkDecoderSilesia-32 5 206878840 ns/op 1024.50 MB/s 49808 B/op 43 allocs/op +BenchmarkDecoderEnwik9-32 1 1271809000 ns/op 786.28 MB/s 72048 B/op 52 allocs/op -BenchmarkDecoderEnwik9-8 1 2027001600 ns/op 493.34 MB/s 10496 B/op 18 allocs/op -BenchmarkDecoderEnwik9Cgo-8 2 979499200 ns/op 1020.93 MB/s 270672 B/op 8 allocs/op +Concurrent blocks, performance: -Concurrent performance: - -BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-16 28915 42469 ns/op 4340.07 MB/s 114 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-16 116505 9965 ns/op 11900.16 MB/s 16 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-16 8952 134272 ns/op 3588.70 MB/s 915 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-16 11820 102538 ns/op 4161.90 MB/s 594 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-16 34782 34184 ns/op 3661.88 MB/s 60 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-16 27712 43447 ns/op 3500.58 MB/s 99 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-16 62826 18750 ns/op 21845.10 MB/s 104 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-16 631545 1794 ns/op 57078.74 MB/s 2 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-16 1690140 712 ns/op 172938.13 MB/s 1 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-16 10432 113593 ns/op 6180.73 MB/s 1143 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/html.zst-16 113206 10671 ns/op 9596.27 MB/s 15 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-16 1530615 779 ns/op 5229.49 MB/s 0 B/op 0 allocs/op - -BenchmarkDecoder_DecodeAllParallelCgo/kppkn.gtb.zst-16 65217 16192 ns/op 11383.34 MB/s 46 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/geo.protodata.zst-16 292671 4039 ns/op 29363.19 MB/s 6 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/plrabn12.txt.zst-16 26314 46021 ns/op 10470.43 MB/s 293 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/lcet10.txt.zst-16 33897 34900 ns/op 12227.96 MB/s 205 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/asyoulik.txt.zst-16 104348 11433 ns/op 10949.01 MB/s 20 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/alice29.txt.zst-16 75949 15510 ns/op 9805.60 MB/s 32 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/html_x_4.zst-16 173910 6756 ns/op 60624.29 MB/s 37 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/paper-100k.pdf.zst-16 923076 1339 ns/op 76474.87 MB/s 1 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/fireworks.jpeg.zst-16 922920 1351 ns/op 91102.57 MB/s 2 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/urls.10K.zst-16 27649 43618 ns/op 16096.19 MB/s 407 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/html.zst-16 279073 4160 ns/op 24614.18 MB/s 6 B/op 0 allocs/op -BenchmarkDecoder_DecodeAllParallelCgo/comp-data.bin.zst-16 749938 1579 ns/op 2581.71 MB/s 0 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-32 67356 17857 ns/op 10321.96 MB/s 22.48 pct 102 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-32 266656 4421 ns/op 26823.21 MB/s 11.89 pct 19 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-32 20992 56842 ns/op 8477.17 MB/s 39.90 pct 754 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-32 27456 43932 ns/op 9714.01 MB/s 33.27 pct 524 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-32 78432 15047 ns/op 8319.15 MB/s 40.34 pct 66 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-32 65800 18436 ns/op 8249.63 MB/s 37.75 pct 88 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-32 102993 11523 ns/op 35546.09 MB/s 3.637 pct 143 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-32 1000000 1070 ns/op 95720.98 MB/s 80.53 pct 3 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-32 749802 1752 ns/op 70272.35 MB/s 100.0 pct 5 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-32 22640 52934 ns/op 13263.37 MB/s 26.25 pct 1014 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/html.zst-32 226412 5232 ns/op 19572.27 MB/s 14.49 pct 20 B/op 0 allocs/op +BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-32 923041 1276 ns/op 3194.71 MB/s 31.26 pct 0 B/op 0 allocs/op ``` -This reflects the performance around May 2020, but this may be out of date. +This reflects the performance around May 2022, but this may be out of date. ## Zstd inside ZIP files diff --git a/vendor/github.com/klauspost/compress/zstd/bitreader.go b/vendor/github.com/klauspost/compress/zstd/bitreader.go index d7cd15ba2..97299d499 100644 --- a/vendor/github.com/klauspost/compress/zstd/bitreader.go +++ b/vendor/github.com/klauspost/compress/zstd/bitreader.go @@ -63,13 +63,6 @@ func (b *bitReader) get32BitsFast(n uint8) uint32 { return v } -func (b *bitReader) get16BitsFast(n uint8) uint16 { - const regMask = 64 - 1 - v := uint16((b.value << (b.bitsRead & regMask)) >> ((regMask + 1 - n) & regMask)) - b.bitsRead += n - return v -} - // fillFast() will make sure at least 32 bits are available. // There must be at least 4 bytes available. func (b *bitReader) fillFast() { diff --git a/vendor/github.com/klauspost/compress/zstd/bitwriter.go b/vendor/github.com/klauspost/compress/zstd/bitwriter.go index b36618285..78b3c61be 100644 --- a/vendor/github.com/klauspost/compress/zstd/bitwriter.go +++ b/vendor/github.com/klauspost/compress/zstd/bitwriter.go @@ -5,8 +5,6 @@ package zstd -import "fmt" - // bitWriter will write bits. // First bit will be LSB of the first byte of output. type bitWriter struct { @@ -73,80 +71,6 @@ func (b *bitWriter) addBits16Clean(value uint16, bits uint8) { b.nBits += bits } -// flush will flush all pending full bytes. -// There will be at least 56 bits available for writing when this has been called. -// Using flush32 is faster, but leaves less space for writing. -func (b *bitWriter) flush() { - v := b.nBits >> 3 - switch v { - case 0: - case 1: - b.out = append(b.out, - byte(b.bitContainer), - ) - case 2: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - ) - case 3: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - ) - case 4: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - ) - case 5: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - ) - case 6: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - ) - case 7: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - ) - case 8: - b.out = append(b.out, - byte(b.bitContainer), - byte(b.bitContainer>>8), - byte(b.bitContainer>>16), - byte(b.bitContainer>>24), - byte(b.bitContainer>>32), - byte(b.bitContainer>>40), - byte(b.bitContainer>>48), - byte(b.bitContainer>>56), - ) - default: - panic(fmt.Errorf("bits (%d) > 64", b.nBits)) - } - b.bitContainer >>= v << 3 - b.nBits &= 7 -} - // flush32 will flush out, so there are at least 32 bits available for writing. func (b *bitWriter) flush32() { if b.nBits < 32 { diff --git a/vendor/github.com/klauspost/compress/zstd/blockdec.go b/vendor/github.com/klauspost/compress/zstd/blockdec.go index 7d567a54a..f52d1aed6 100644 --- a/vendor/github.com/klauspost/compress/zstd/blockdec.go +++ b/vendor/github.com/klauspost/compress/zstd/blockdec.go @@ -5,9 +5,13 @@ package zstd import ( + "bytes" + "encoding/binary" "errors" "fmt" "io" + "os" + "path/filepath" "sync" "github.com/klauspost/compress/huff0" @@ -38,14 +42,14 @@ const ( // maxCompressedBlockSize is the biggest allowed compressed block size (128KB) maxCompressedBlockSize = 128 << 10 + compressedBlockOverAlloc = 16 + maxCompressedBlockSizeAlloc = 128<<10 + compressedBlockOverAlloc + // Maximum possible block size (all Raw+Uncompressed). maxBlockSize = (1 << 21) - 1 - // https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#literals_section_header - maxCompressedLiteralSize = 1 << 18 - maxRLELiteralSize = 1 << 20 - maxMatchLen = 131074 - maxSequences = 0x7f00 + 0xffff + maxMatchLen = 131074 + maxSequences = 0x7f00 + 0xffff // We support slightly less than the reference decoder to be able to // use ints on 32 bit archs. @@ -97,7 +101,6 @@ type blockDec struct { // Block is RLE, this is the size. RLESize uint32 - tmp [4]byte Type blockType @@ -136,7 +139,7 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { b.Type = blockType((bh >> 1) & 3) // find size. cSize := int(bh >> 3) - maxSize := maxBlockSize + maxSize := maxCompressedBlockSizeAlloc switch b.Type { case blockTypeReserved: return ErrReservedBlockType @@ -157,9 +160,9 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { println("Data size on stream:", cSize) } b.RLESize = 0 - maxSize = maxCompressedBlockSize + maxSize = maxCompressedBlockSizeAlloc if windowSize < maxCompressedBlockSize && b.lowMem { - maxSize = int(windowSize) + maxSize = int(windowSize) + compressedBlockOverAlloc } if cSize > maxCompressedBlockSize || uint64(cSize) > b.WindowSize { if debugDecoder { @@ -190,9 +193,9 @@ func (b *blockDec) reset(br byteBuffer, windowSize uint64) error { // Read block data. if cap(b.dataStorage) < cSize { if b.lowMem || cSize > maxCompressedBlockSize { - b.dataStorage = make([]byte, 0, cSize) + b.dataStorage = make([]byte, 0, cSize+compressedBlockOverAlloc) } else { - b.dataStorage = make([]byte, 0, maxCompressedBlockSize) + b.dataStorage = make([]byte, 0, maxCompressedBlockSizeAlloc) } } if cap(b.dst) <= maxSize { @@ -360,14 +363,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err } if cap(b.literalBuf) < litRegenSize { if b.lowMem { - b.literalBuf = make([]byte, litRegenSize) + b.literalBuf = make([]byte, litRegenSize, litRegenSize+compressedBlockOverAlloc) } else { - if litRegenSize > maxCompressedLiteralSize { - // Exceptional - b.literalBuf = make([]byte, litRegenSize) - } else { - b.literalBuf = make([]byte, litRegenSize, maxCompressedLiteralSize) - } + b.literalBuf = make([]byte, litRegenSize, maxCompressedBlockSize+compressedBlockOverAlloc) } } literals = b.literalBuf[:litRegenSize] @@ -397,14 +395,14 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err // Ensure we have space to store it. if cap(b.literalBuf) < litRegenSize { if b.lowMem { - b.literalBuf = make([]byte, 0, litRegenSize) + b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc) } else { - b.literalBuf = make([]byte, 0, maxCompressedLiteralSize) + b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc) } } var err error // Use our out buffer. - huff.MaxDecodedSize = maxCompressedBlockSize + huff.MaxDecodedSize = litRegenSize if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) } else { @@ -429,9 +427,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err // Ensure we have space to store it. if cap(b.literalBuf) < litRegenSize { if b.lowMem { - b.literalBuf = make([]byte, 0, litRegenSize) + b.literalBuf = make([]byte, 0, litRegenSize+compressedBlockOverAlloc) } else { - b.literalBuf = make([]byte, 0, maxCompressedBlockSize) + b.literalBuf = make([]byte, 0, maxCompressedBlockSize+compressedBlockOverAlloc) } } huff := hist.huffTree @@ -448,7 +446,7 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err return in, err } hist.huffTree = huff - huff.MaxDecodedSize = maxCompressedBlockSize + huff.MaxDecodedSize = litRegenSize // Use our out buffer. if fourStreams { literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals) @@ -463,6 +461,8 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err if len(literals) != litRegenSize { return in, fmt.Errorf("literal output size mismatch want %d, got %d", litRegenSize, len(literals)) } + // Re-cap to get extra size. + literals = b.literalBuf[:len(literals)] if debugDecoder { printf("Decompressed %d literals into %d bytes\n", litCompSize, litRegenSize) } @@ -486,10 +486,15 @@ func (b *blockDec) decodeCompressed(hist *history) error { b.dst = append(b.dst, hist.decoders.literals...) return nil } - err = hist.decoders.decodeSync(hist) + before := len(hist.decoders.out) + err = hist.decoders.decodeSync(hist.b[hist.ignoreBuffer:]) if err != nil { return err } + if hist.decoders.maxSyncLen > 0 { + hist.decoders.maxSyncLen += uint64(before) + hist.decoders.maxSyncLen -= uint64(len(hist.decoders.out)) + } b.dst = hist.decoders.out hist.recentOffsets = hist.decoders.prevOffset return nil @@ -632,6 +637,22 @@ func (b *blockDec) prepareSequences(in []byte, hist *history) (err error) { println("initializing sequences:", err) return err } + // Extract blocks... + if false && hist.dict == nil { + fatalErr := func(err error) { + if err != nil { + panic(err) + } + } + fn := fmt.Sprintf("n-%d-lits-%d-prev-%d-%d-%d-win-%d.blk", hist.decoders.nSeqs, len(hist.decoders.literals), hist.recentOffsets[0], hist.recentOffsets[1], hist.recentOffsets[2], hist.windowSize) + var buf bytes.Buffer + fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.litLengths.fse)) + fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.matchLengths.fse)) + fatalErr(binary.Write(&buf, binary.LittleEndian, hist.decoders.offsets.fse)) + buf.Write(in) + os.WriteFile(filepath.Join("testdata", "seqs", fn), buf.Bytes(), os.ModePerm) + } + return nil } @@ -650,6 +671,7 @@ func (b *blockDec) decodeSequences(hist *history) error { } hist.decoders.windowSize = hist.windowSize hist.decoders.prevOffset = hist.recentOffsets + err := hist.decoders.decode(b.sequence) hist.recentOffsets = hist.decoders.prevOffset return err diff --git a/vendor/github.com/klauspost/compress/zstd/bytebuf.go b/vendor/github.com/klauspost/compress/zstd/bytebuf.go index b80191e4b..176788f25 100644 --- a/vendor/github.com/klauspost/compress/zstd/bytebuf.go +++ b/vendor/github.com/klauspost/compress/zstd/bytebuf.go @@ -7,7 +7,6 @@ package zstd import ( "fmt" "io" - "io/ioutil" ) type byteBuffer interface { @@ -23,7 +22,7 @@ type byteBuffer interface { readByte() (byte, error) // Skip n bytes. - skipN(n int) error + skipN(n int64) error } // in-memory buffer @@ -52,10 +51,6 @@ func (b *byteBuf) readBig(n int, dst []byte) ([]byte, error) { return r, nil } -func (b *byteBuf) remain() []byte { - return *b -} - func (b *byteBuf) readByte() (byte, error) { bb := *b if len(bb) < 1 { @@ -66,9 +61,12 @@ func (b *byteBuf) readByte() (byte, error) { return r, nil } -func (b *byteBuf) skipN(n int) error { +func (b *byteBuf) skipN(n int64) error { bb := *b - if len(bb) < n { + if n < 0 { + return fmt.Errorf("negative skip (%d) requested", n) + } + if int64(len(bb)) < n { return io.ErrUnexpectedEOF } *b = bb[n:] @@ -124,9 +122,9 @@ func (r *readerWrapper) readByte() (byte, error) { return r.tmp[0], nil } -func (r *readerWrapper) skipN(n int) error { - n2, err := io.CopyN(ioutil.Discard, r.r, int64(n)) - if n2 != int64(n) { +func (r *readerWrapper) skipN(n int64) error { + n2, err := io.CopyN(io.Discard, r.r, n) + if n2 != n { err = io.ErrUnexpectedEOF } return err diff --git a/vendor/github.com/klauspost/compress/zstd/bytereader.go b/vendor/github.com/klauspost/compress/zstd/bytereader.go index 2c4fca17f..0e59a242d 100644 --- a/vendor/github.com/klauspost/compress/zstd/bytereader.go +++ b/vendor/github.com/klauspost/compress/zstd/bytereader.go @@ -13,12 +13,6 @@ type byteReader struct { off int } -// init will initialize the reader and set the input. -func (b *byteReader) init(in []byte) { - b.b = in - b.off = 0 -} - // advance the stream b n bytes. func (b *byteReader) advance(n uint) { b.off += int(n) diff --git a/vendor/github.com/klauspost/compress/zstd/decoder.go b/vendor/github.com/klauspost/compress/zstd/decoder.go index 9fcdaac1d..6104eb793 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder.go @@ -312,6 +312,7 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { // Grab a block decoder and frame decoder. block := <-d.decoders frame := block.localFrame + initialSize := len(dst) defer func() { if debugDecoder { printf("re-adding decoder: %p", block) @@ -347,19 +348,33 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { } frame.history.setDict(&dict) } - - if frame.FrameContentSize != fcsUnknown && frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)) { - return dst, ErrDecoderSizeExceeded + if frame.WindowSize > d.o.maxWindowSize { + if debugDecoder { + println("window size exceeded:", frame.WindowSize, ">", d.o.maxWindowSize) + } + return dst, ErrWindowSizeExceeded } - if frame.FrameContentSize < 1<<30 { - // Never preallocate more than 1 GB up front. + if frame.FrameContentSize != fcsUnknown { + if frame.FrameContentSize > d.o.maxDecodedSize-uint64(len(dst)-initialSize) { + if debugDecoder { + println("decoder size exceeded; fcs:", frame.FrameContentSize, "> mcs:", d.o.maxDecodedSize-uint64(len(dst)-initialSize), "len:", len(dst)) + } + return dst, ErrDecoderSizeExceeded + } + if d.o.limitToCap && frame.FrameContentSize > uint64(cap(dst)-len(dst)) { + if debugDecoder { + println("decoder size exceeded; fcs:", frame.FrameContentSize, "> (cap-len)", cap(dst)-len(dst)) + } + return dst, ErrDecoderSizeExceeded + } if cap(dst)-len(dst) < int(frame.FrameContentSize) { - dst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize)) + dst2 := make([]byte, len(dst), len(dst)+int(frame.FrameContentSize)+compressedBlockOverAlloc) copy(dst2, dst) dst = dst2 } } - if cap(dst) == 0 { + + if cap(dst) == 0 && !d.o.limitToCap { // Allocate len(input) * 2 by default if nothing is provided // and we didn't get frame content size. size := len(input) * 2 @@ -377,6 +392,9 @@ func (d *Decoder) DecodeAll(input, dst []byte) ([]byte, error) { if err != nil { return dst, err } + if uint64(len(dst)-initialSize) > d.o.maxDecodedSize { + return dst, ErrDecoderSizeExceeded + } if len(frame.bBuf) == 0 { if debugDecoder { println("frame dbuf empty") @@ -437,7 +455,7 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) { println("got", len(d.current.b), "bytes, error:", d.current.err, "data crc:", tmp) } - if len(next.b) > 0 { + if !d.o.ignoreChecksum && len(next.b) > 0 { n, err := d.current.crc.Write(next.b) if err == nil { if n != len(next.b) { @@ -449,7 +467,7 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) { got := d.current.crc.Sum64() var tmp [4]byte binary.LittleEndian.PutUint32(tmp[:], uint32(got)) - if !bytes.Equal(tmp[:], next.d.checkCRC) && !ignoreCRC { + if !d.o.ignoreChecksum && !bytes.Equal(tmp[:], next.d.checkCRC) { if debugDecoder { println("CRC Check Failed:", tmp[:], " (got) !=", next.d.checkCRC, "(on stream)") } @@ -533,9 +551,15 @@ func (d *Decoder) nextBlockSync() (ok bool) { // Update/Check CRC if d.frame.HasCheckSum { - d.frame.crc.Write(d.current.b) + if !d.o.ignoreChecksum { + d.frame.crc.Write(d.current.b) + } if d.current.d.Last { - d.current.err = d.frame.checkCRC() + if !d.o.ignoreChecksum { + d.current.err = d.frame.checkCRC() + } else { + d.current.err = d.frame.consumeCRC() + } if d.current.err != nil { println("CRC error:", d.current.err) return false @@ -629,60 +653,18 @@ func (d *Decoder) startSyncDecoder(r io.Reader) error { // Create Decoder: // ASYNC: -// Spawn 4 go routines. -// 0: Read frames and decode blocks. -// 1: Decode block and literals. Receives hufftree and seqdecs, returns seqdecs and huff tree. -// 2: Wait for recentOffsets if needed. Decode sequences, send recentOffsets. -// 3: Wait for stream history, execute sequences, send stream history. +// Spawn 3 go routines. +// 0: Read frames and decode block literals. +// 1: Decode sequences. +// 2: Execute sequences, send to output. func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output chan decodeOutput) { defer d.streamWg.Done() br := readerWrapper{r: r} - var seqPrepare = make(chan *blockDec, d.o.concurrent) var seqDecode = make(chan *blockDec, d.o.concurrent) var seqExecute = make(chan *blockDec, d.o.concurrent) - // Async 1: Prepare blocks... - go func() { - var hist history - var hasErr bool - for block := range seqPrepare { - if hasErr { - if block != nil { - seqDecode <- block - } - continue - } - if block.async.newHist != nil { - if debugDecoder { - println("Async 1: new history") - } - hist.reset() - if block.async.newHist.dict != nil { - hist.setDict(block.async.newHist.dict) - } - } - if block.err != nil || block.Type != blockTypeCompressed { - hasErr = block.err != nil - seqDecode <- block - continue - } - - remain, err := block.decodeLiterals(block.data, &hist) - block.err = err - hasErr = block.err != nil - if err == nil { - block.async.literals = hist.decoders.literals - block.async.seqData = remain - } else if debugDecoder { - println("decodeLiterals error:", err) - } - seqDecode <- block - } - close(seqDecode) - }() - - // Async 2: Decode sequences... + // Async 1: Decode sequences... go func() { var hist history var hasErr bool @@ -696,7 +678,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch } if block.async.newHist != nil { if debugDecoder { - println("Async 2: new history, recent:", block.async.newHist.recentOffsets) + println("Async 1: new history, recent:", block.async.newHist.recentOffsets) } hist.decoders = block.async.newHist.decoders hist.recentOffsets = block.async.newHist.recentOffsets @@ -750,7 +732,7 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch } if block.async.newHist != nil { if debugDecoder { - println("Async 3: new history") + println("Async 2: new history") } hist.windowSize = block.async.newHist.windowSize hist.allocFrameBuffer = block.async.newHist.allocFrameBuffer @@ -837,6 +819,33 @@ func (d *Decoder) startStreamDecoder(ctx context.Context, r io.Reader, output ch decodeStream: for { + var hist history + var hasErr bool + + decodeBlock := func(block *blockDec) { + if hasErr { + if block != nil { + seqDecode <- block + } + return + } + if block.err != nil || block.Type != blockTypeCompressed { + hasErr = block.err != nil + seqDecode <- block + return + } + + remain, err := block.decodeLiterals(block.data, &hist) + block.err = err + hasErr = block.err != nil + if err == nil { + block.async.literals = hist.decoders.literals + block.async.seqData = remain + } else if debugDecoder { + println("decodeLiterals error:", err) + } + seqDecode <- block + } frame := d.frame if debugDecoder { println("New frame...") @@ -856,6 +865,10 @@ decodeStream: } } if err == nil && d.frame.WindowSize > d.o.maxWindowSize { + if debugDecoder { + println("decoder size exceeded, fws:", d.frame.WindowSize, "> mws:", d.o.maxWindowSize) + } + err = ErrDecoderSizeExceeded } if err != nil { @@ -863,7 +876,7 @@ decodeStream: case <-ctx.Done(): case dec := <-d.decoders: dec.sendErr(err) - seqPrepare <- dec + decodeBlock(dec) } break decodeStream } @@ -883,6 +896,10 @@ decodeStream: if debugDecoder { println("Alloc History:", h.allocFrameBuffer) } + hist.reset() + if h.dict != nil { + hist.setDict(h.dict) + } dec.async.newHist = &h dec.async.fcs = frame.FrameContentSize historySent = true @@ -909,7 +926,7 @@ decodeStream: } err = dec.err last := dec.Last - seqPrepare <- dec + decodeBlock(dec) if err != nil { break decodeStream } @@ -918,7 +935,7 @@ decodeStream: } } } - close(seqPrepare) + close(seqDecode) wg.Wait() d.frame.history.b = frameHistCache } diff --git a/vendor/github.com/klauspost/compress/zstd/decoder_options.go b/vendor/github.com/klauspost/compress/zstd/decoder_options.go index fd05c9bb0..666c2715f 100644 --- a/vendor/github.com/klauspost/compress/zstd/decoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/decoder_options.go @@ -19,6 +19,8 @@ type decoderOptions struct { maxDecodedSize uint64 maxWindowSize uint64 dicts []dict + ignoreChecksum bool + limitToCap bool } func (o *decoderOptions) setDefault() { @@ -31,7 +33,7 @@ func (o *decoderOptions) setDefault() { if o.concurrent > 4 { o.concurrent = 4 } - o.maxDecodedSize = 1 << 63 + o.maxDecodedSize = 64 << 30 } // WithDecoderLowmem will set whether to use a lower amount of memory, @@ -66,7 +68,7 @@ func WithDecoderConcurrency(n int) DOption { // WithDecoderMaxMemory allows to set a maximum decoded size for in-memory // non-streaming operations or maximum window size for streaming operations. // This can be used to control memory usage of potentially hostile content. -// Maximum and default is 1 << 63 bytes. +// Maximum is 1 << 63 bytes. Default is 64GiB. func WithDecoderMaxMemory(n uint64) DOption { return func(o *decoderOptions) error { if n == 0 { @@ -112,3 +114,22 @@ func WithDecoderMaxWindow(size uint64) DOption { return nil } } + +// WithDecodeAllCapLimit will limit DecodeAll to decoding cap(dst)-len(dst) bytes, +// or any size set in WithDecoderMaxMemory. +// This can be used to limit decoding to a specific maximum output size. +// Disabled by default. +func WithDecodeAllCapLimit(b bool) DOption { + return func(o *decoderOptions) error { + o.limitToCap = b + return nil + } +} + +// IgnoreChecksum allows to forcibly ignore checksum checking. +func IgnoreChecksum(b bool) DOption { + return func(o *decoderOptions) error { + o.ignoreChecksum = b + return nil + } +} diff --git a/vendor/github.com/klauspost/compress/zstd/enc_better.go b/vendor/github.com/klauspost/compress/zstd/enc_better.go index 602c05ee0..d70e3fd3d 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_better.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_better.go @@ -156,8 +156,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -416,15 +416,23 @@ encodeLoop: // Try to find a better match by searching for a long match at the end of the current best match if s+matched < sLimit { + // Allow some bytes at the beginning to mismatch. + // Sweet spot is around 3 bytes, but depends on input. + // The skipped bytes are tested in Extend backwards, + // and still picked up as part of the match if they do. + const skipBeginning = 3 + nextHashL := hashLen(load6432(src, s+matched), betterLongTableBits, betterLongLen) - cv := load3232(src, s) + s2 := s + skipBeginning + cv := load3232(src, s2) candidateL := e.longTable[nextHashL] - coffsetL := candidateL.offset - e.cur - matched - if coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { + coffsetL := candidateL.offset - e.cur - matched + skipBeginning + if coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { // Found a long match, at least 4 bytes. - matchedNext := e.matchlen(s+4, coffsetL+4, src) + 4 + matchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4 if matchedNext > matched { t = coffsetL + s = s2 matched = matchedNext if debugMatches { println("long match at end-of-match") @@ -434,12 +442,13 @@ encodeLoop: // Check prev long... if true { - coffsetL = candidateL.prev - e.cur - matched - if coffsetL >= 0 && coffsetL < s && s-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { + coffsetL = candidateL.prev - e.cur - matched + skipBeginning + if coffsetL >= 0 && coffsetL < s2 && s2-coffsetL < e.maxMatchOff && cv == load3232(src, coffsetL) { // Found a long match, at least 4 bytes. - matchedNext := e.matchlen(s+4, coffsetL+4, src) + 4 + matchedNext := e.matchlen(s2+4, coffsetL+4, src) + 4 if matchedNext > matched { t = coffsetL + s = s2 matched = matchedNext if debugMatches { println("prev long match at end-of-match") @@ -518,8 +527,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -674,8 +683,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -1047,8 +1056,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) nextHashL := hashLen(cv, betterLongTableBits, betterLongLen) + nextHashS := hashLen(cv, betterShortTableBits, betterShortLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match diff --git a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go index d6b310424..1f4a9a245 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_dfast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_dfast.go @@ -127,8 +127,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -439,8 +439,8 @@ encodeLoop: var t int32 for { - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -785,8 +785,8 @@ encodeLoop: panic("offset0 was 0") } - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) candidateL := e.longTable[nextHashL] candidateS := e.table[nextHashS] @@ -969,7 +969,7 @@ encodeLoop: te0 := tableEntry{offset: index0 + e.cur, val: uint32(cv0)} te1 := tableEntry{offset: index1 + e.cur, val: uint32(cv1)} longHash1 := hashLen(cv0, dFastLongTableBits, dFastLongLen) - longHash2 := hashLen(cv0, dFastLongTableBits, dFastLongLen) + longHash2 := hashLen(cv1, dFastLongTableBits, dFastLongLen) e.longTable[longHash1] = te0 e.longTable[longHash2] = te1 e.markLongShardDirty(longHash1) @@ -1002,8 +1002,8 @@ encodeLoop: } // Store this, since we have it. - nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) nextHashL := hashLen(cv, dFastLongTableBits, dFastLongLen) + nextHashS := hashLen(cv, dFastShortTableBits, dFastShortLen) // We have at least 4 byte match. // No need to check backwards. We come straight from a match @@ -1103,7 +1103,8 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { } if allDirty || dirtyShardCnt > dLongTableShardCnt/2 { - copy(e.longTable[:], e.dictLongTable) + //copy(e.longTable[:], e.dictLongTable) + e.longTable = *(*[dFastLongTableSize]tableEntry)(e.dictLongTable) for i := range e.longTableShardDirty { e.longTableShardDirty[i] = false } @@ -1114,7 +1115,9 @@ func (e *doubleFastEncoderDict) Reset(d *dict, singleBlock bool) { continue } - copy(e.longTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize], e.dictLongTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize]) + // copy(e.longTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize], e.dictLongTable[i*dLongTableShardSize:(i+1)*dLongTableShardSize]) + *(*[dLongTableShardSize]tableEntry)(e.longTable[i*dLongTableShardSize:]) = *(*[dLongTableShardSize]tableEntry)(e.dictLongTable[i*dLongTableShardSize:]) + e.longTableShardDirty[i] = false } } diff --git a/vendor/github.com/klauspost/compress/zstd/enc_fast.go b/vendor/github.com/klauspost/compress/zstd/enc_fast.go index f51ab529a..181edc02b 100644 --- a/vendor/github.com/klauspost/compress/zstd/enc_fast.go +++ b/vendor/github.com/klauspost/compress/zstd/enc_fast.go @@ -871,7 +871,8 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { const shardCnt = tableShardCnt const shardSize = tableShardSize if e.allDirty || dirtyShardCnt > shardCnt*4/6 { - copy(e.table[:], e.dictTable) + //copy(e.table[:], e.dictTable) + e.table = *(*[tableSize]tableEntry)(e.dictTable) for i := range e.tableShardDirty { e.tableShardDirty[i] = false } @@ -883,7 +884,8 @@ func (e *fastEncoderDict) Reset(d *dict, singleBlock bool) { continue } - copy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize]) + //copy(e.table[i*shardSize:(i+1)*shardSize], e.dictTable[i*shardSize:(i+1)*shardSize]) + *(*[shardSize]tableEntry)(e.table[i*shardSize:]) = *(*[shardSize]tableEntry)(e.dictTable[i*shardSize:]) e.tableShardDirty[i] = false } e.allDirty = false diff --git a/vendor/github.com/klauspost/compress/zstd/encoder.go b/vendor/github.com/klauspost/compress/zstd/encoder.go index dcc987a7c..7aaaedb23 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder.go @@ -528,8 +528,8 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte { // If a non-single block is needed the encoder will reset again. e.encoders <- enc }() - // Use single segments when above minimum window and below 1MB. - single := len(src) < 1<<20 && len(src) > MinWindowSize + // Use single segments when above minimum window and below window size. + single := len(src) <= e.o.windowSize && len(src) > MinWindowSize if e.o.single != nil { single = *e.o.single } @@ -551,7 +551,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte { } // If we can do everything in one block, prefer that. - if len(src) <= maxCompressedBlockSize { + if len(src) <= e.o.blockSize { enc.Reset(e.o.dict, true) // Slightly faster with no history and everything in one block. if e.o.crc { diff --git a/vendor/github.com/klauspost/compress/zstd/encoder_options.go b/vendor/github.com/klauspost/compress/zstd/encoder_options.go index 44d8dbd19..a7c5e1aac 100644 --- a/vendor/github.com/klauspost/compress/zstd/encoder_options.go +++ b/vendor/github.com/klauspost/compress/zstd/encoder_options.go @@ -283,7 +283,7 @@ func WithNoEntropyCompression(b bool) EOption { // a decoder is allowed to reject a compressed frame which requests a memory size beyond decoder's authorized range. // For broader compatibility, decoders are recommended to support memory sizes of at least 8 MB. // This is only a recommendation, each decoder is free to support higher or lower limits, depending on local limitations. -// If this is not specified, block encodes will automatically choose this based on the input size. +// If this is not specified, block encodes will automatically choose this based on the input size and the window size. // This setting has no effect on streamed encodes. func WithSingleSegment(b bool) EOption { return func(o *encoderOptions) error { diff --git a/vendor/github.com/klauspost/compress/zstd/framedec.go b/vendor/github.com/klauspost/compress/zstd/framedec.go index 11089d223..1559a2038 100644 --- a/vendor/github.com/klauspost/compress/zstd/framedec.go +++ b/vendor/github.com/klauspost/compress/zstd/framedec.go @@ -106,7 +106,7 @@ func (d *frameDec) reset(br byteBuffer) error { } n := uint32(b[0]) | (uint32(b[1]) << 8) | (uint32(b[2]) << 16) | (uint32(b[3]) << 24) println("Skipping frame with", n, "bytes.") - err = br.skipN(int(n)) + err = br.skipN(int64(n)) if err != nil { if debugDecoder { println("Reading discarded frame", err) @@ -231,20 +231,27 @@ func (d *frameDec) reset(br byteBuffer) error { d.crc.Reset() } + if d.WindowSize > d.o.maxWindowSize { + if debugDecoder { + printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) + } + return ErrWindowSizeExceeded + } + if d.WindowSize == 0 && d.SingleSegment { // We may not need window in this case. d.WindowSize = d.FrameContentSize if d.WindowSize < MinWindowSize { d.WindowSize = MinWindowSize } + if d.WindowSize > d.o.maxDecodedSize { + if debugDecoder { + printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) + } + return ErrDecoderSizeExceeded + } } - if d.WindowSize > uint64(d.o.maxWindowSize) { - if debugDecoder { - printf("window size %d > max %d\n", d.WindowSize, d.o.maxWindowSize) - } - return ErrWindowSizeExceeded - } // The minimum Window_Size is 1 KB. if d.WindowSize < MinWindowSize { if debugDecoder { @@ -253,10 +260,11 @@ func (d *frameDec) reset(br byteBuffer) error { return ErrWindowSizeTooSmall } d.history.windowSize = int(d.WindowSize) - if d.o.lowMem && d.history.windowSize < maxBlockSize { + if !d.o.lowMem || d.history.windowSize < maxBlockSize { + // Alloc 2x window size if not low-mem, or very small window size. d.history.allocFrameBuffer = d.history.windowSize * 2 - // TODO: Maybe use FrameContent size } else { + // Alloc with one additional block d.history.allocFrameBuffer = d.history.windowSize + maxBlockSize } @@ -290,13 +298,6 @@ func (d *frameDec) checkCRC() error { if !d.HasCheckSum { return nil } - var tmp [4]byte - got := d.crc.Sum64() - // Flip to match file order. - tmp[0] = byte(got >> 0) - tmp[1] = byte(got >> 8) - tmp[2] = byte(got >> 16) - tmp[3] = byte(got >> 24) // We can overwrite upper tmp now want, err := d.rawInput.readSmall(4) @@ -305,7 +306,19 @@ func (d *frameDec) checkCRC() error { return err } - if !bytes.Equal(tmp[:], want) && !ignoreCRC { + if d.o.ignoreChecksum { + return nil + } + + var tmp [4]byte + got := d.crc.Sum64() + // Flip to match file order. + tmp[0] = byte(got >> 0) + tmp[1] = byte(got >> 8) + tmp[2] = byte(got >> 16) + tmp[3] = byte(got >> 24) + + if !bytes.Equal(tmp[:], want) { if debugDecoder { println("CRC Check Failed:", tmp[:], "!=", want) } @@ -317,6 +330,19 @@ func (d *frameDec) checkCRC() error { return nil } +// consumeCRC reads the checksum data if the frame has one. +func (d *frameDec) consumeCRC() error { + if d.HasCheckSum { + _, err := d.rawInput.readSmall(4) + if err != nil { + println("CRC missing?", err) + return err + } + } + + return nil +} + // runDecoder will create a sync decoder that will decode a block of data. func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { saved := d.history.b @@ -326,6 +352,30 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { d.history.ignoreBuffer = len(dst) // Store input length, so we only check new data. crcStart := len(dst) + d.history.decoders.maxSyncLen = 0 + if d.o.limitToCap { + d.history.decoders.maxSyncLen = uint64(cap(dst) - len(dst)) + } + if d.FrameContentSize != fcsUnknown { + if !d.o.limitToCap || d.FrameContentSize+uint64(len(dst)) < d.history.decoders.maxSyncLen { + d.history.decoders.maxSyncLen = d.FrameContentSize + uint64(len(dst)) + } + if d.history.decoders.maxSyncLen > d.o.maxDecodedSize { + if debugDecoder { + println("maxSyncLen:", d.history.decoders.maxSyncLen, "> maxDecodedSize:", d.o.maxDecodedSize) + } + return dst, ErrDecoderSizeExceeded + } + if debugDecoder { + println("maxSyncLen:", d.history.decoders.maxSyncLen) + } + if !d.o.limitToCap && uint64(cap(dst)-len(dst)) < d.history.decoders.maxSyncLen { + // Alloc for output + dst2 := make([]byte, len(dst), d.history.decoders.maxSyncLen+compressedBlockOverAlloc) + copy(dst2, dst) + dst = dst2 + } + } var err error for { err = dec.reset(d.rawInput, d.WindowSize) @@ -339,7 +389,13 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { if err != nil { break } - if uint64(len(d.history.b)) > d.o.maxDecodedSize { + if uint64(len(d.history.b)-crcStart) > d.o.maxDecodedSize { + println("runDecoder: maxDecodedSize exceeded", uint64(len(d.history.b)-crcStart), ">", d.o.maxDecodedSize) + err = ErrDecoderSizeExceeded + break + } + if d.o.limitToCap && len(d.history.b) > cap(dst) { + println("runDecoder: cap exceeded", uint64(len(d.history.b)), ">", cap(dst)) err = ErrDecoderSizeExceeded break } @@ -360,13 +416,17 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) { if d.FrameContentSize != fcsUnknown && uint64(len(d.history.b)-crcStart) != d.FrameContentSize { err = ErrFrameSizeMismatch } else if d.HasCheckSum { - var n int - n, err = d.crc.Write(dst[crcStart:]) - if err == nil { - if n != len(dst)-crcStart { - err = io.ErrShortWrite - } else { - err = d.checkCRC() + if d.o.ignoreChecksum { + err = d.consumeCRC() + } else { + var n int + n, err = d.crc.Write(dst[crcStart:]) + if err == nil { + if n != len(dst)-crcStart { + err = io.ErrShortWrite + } else { + err = d.checkCRC() + } } } } diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder.go index bb3d4fd6c..2f8860a72 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_decoder.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder.go @@ -5,8 +5,10 @@ package zstd import ( + "encoding/binary" "errors" "fmt" + "io" ) const ( @@ -178,10 +180,32 @@ func (s *fseDecoder) readNCount(b *byteReader, maxSymbol uint16) error { return fmt.Errorf("corruption detected (total %d != %d)", gotTotal, 1<> 3) - // println(s.norm[:s.symbolLen], s.symbolLen) return s.buildDtable() } +func (s *fseDecoder) mustReadFrom(r io.Reader) { + fatalErr := func(err error) { + if err != nil { + panic(err) + } + } + // dt [maxTablesize]decSymbol // Decompression table. + // symbolLen uint16 // Length of active part of the symbol table. + // actualTableLog uint8 // Selected tablelog. + // maxBits uint8 // Maximum number of additional bits + // // used for table creation to avoid allocations. + // stateTable [256]uint16 + // norm [maxSymbolValue + 1]int16 + // preDefined bool + fatalErr(binary.Read(r, binary.LittleEndian, &s.dt)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.symbolLen)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.actualTableLog)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.maxBits)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.stateTable)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.norm)) + fatalErr(binary.Read(r, binary.LittleEndian, &s.preDefined)) +} + // decSymbol contains information about a state entry, // Including the state offset base, the output symbol and // the number of bits to read for the low part of the destination state. @@ -204,18 +228,10 @@ func (d decSymbol) newState() uint16 { return uint16(d >> 16) } -func (d decSymbol) baseline() uint32 { - return uint32(d >> 32) -} - func (d decSymbol) baselineInt() int { return int(d >> 32) } -func (d *decSymbol) set(nbits, addBits uint8, newState uint16, baseline uint32) { - *d = decSymbol(nbits) | (decSymbol(addBits) << 8) | (decSymbol(newState) << 16) | (decSymbol(baseline) << 32) -} - func (d *decSymbol) setNBits(nBits uint8) { const mask = 0xffffffffffffff00 *d = (*d & mask) | decSymbol(nBits) @@ -231,11 +247,6 @@ func (d *decSymbol) setNewState(state uint16) { *d = (*d & mask) | decSymbol(state)<<16 } -func (d *decSymbol) setBaseline(baseline uint32) { - const mask = 0xffffffff - *d = (*d & mask) | decSymbol(baseline)<<32 -} - func (d *decSymbol) setExt(addBits uint8, baseline uint32) { const mask = 0xffff00ff *d = (*d & mask) | (decSymbol(addBits) << 8) | (decSymbol(baseline) << 32) @@ -257,68 +268,6 @@ func (s *fseDecoder) setRLE(symbol decSymbol) { s.dt[0] = symbol } -// buildDtable will build the decoding table. -func (s *fseDecoder) buildDtable() error { - tableSize := uint32(1 << s.actualTableLog) - highThreshold := tableSize - 1 - symbolNext := s.stateTable[:256] - - // Init, lay down lowprob symbols - { - for i, v := range s.norm[:s.symbolLen] { - if v == -1 { - s.dt[highThreshold].setAddBits(uint8(i)) - highThreshold-- - symbolNext[i] = 1 - } else { - symbolNext[i] = uint16(v) - } - } - } - // Spread symbols - { - tableMask := tableSize - 1 - step := tableStep(tableSize) - position := uint32(0) - for ss, v := range s.norm[:s.symbolLen] { - for i := 0; i < int(v); i++ { - s.dt[position].setAddBits(uint8(ss)) - position = (position + step) & tableMask - for position > highThreshold { - // lowprob area - position = (position + step) & tableMask - } - } - } - if position != 0 { - // position must reach all cells once, otherwise normalizedCounter is incorrect - return errors.New("corrupted input (position != 0)") - } - } - - // Build Decoding table - { - tableSize := uint16(1 << s.actualTableLog) - for u, v := range s.dt[:tableSize] { - symbol := v.addBits() - nextState := symbolNext[symbol] - symbolNext[symbol] = nextState + 1 - nBits := s.actualTableLog - byte(highBits(uint32(nextState))) - s.dt[u&maxTableMask].setNBits(nBits) - newState := (nextState << nBits) - tableSize - if newState > tableSize { - return fmt.Errorf("newState (%d) outside table size (%d)", newState, tableSize) - } - if newState == uint16(u) && nBits == 0 { - // Seems weird that this is possible with nbits > 0. - return fmt.Errorf("newState (%d) == oldState (%d) and no bits", newState, u) - } - s.dt[u&maxTableMask].setNewState(newState) - } - } - return nil -} - // transform will transform the decoder table into a table usable for // decoding without having to apply the transformation while decoding. // The state will contain the base value and the number of bits to read. @@ -352,34 +301,7 @@ func (s *fseState) init(br *bitReader, tableLog uint8, dt []decSymbol) { s.state = dt[br.getBits(tableLog)] } -// next returns the current symbol and sets the next state. -// At least tablelog bits must be available in the bit reader. -func (s *fseState) next(br *bitReader) { - lowBits := uint16(br.getBits(s.state.nbBits())) - s.state = s.dt[s.state.newState()+lowBits] -} - -// finished returns true if all bits have been read from the bitstream -// and the next state would require reading bits from the input. -func (s *fseState) finished(br *bitReader) bool { - return br.finished() && s.state.nbBits() > 0 -} - -// final returns the current state symbol without decoding the next. -func (s *fseState) final() (int, uint8) { - return s.state.baselineInt(), s.state.addBits() -} - // final returns the current state symbol without decoding the next. func (s decSymbol) final() (int, uint8) { return s.baselineInt(), s.addBits() } - -// nextFast returns the next symbol and sets the next state. -// This can only be used if no symbols are 0 bits. -// At least tablelog bits must be available in the bit reader. -func (s *fseState) nextFast(br *bitReader) (uint32, uint8) { - lowBits := br.get16BitsFast(s.state.nbBits()) - s.state = s.dt[s.state.newState()+lowBits] - return s.state.baseline(), s.state.addBits() -} diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go new file mode 100644 index 000000000..c881d28d8 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.go @@ -0,0 +1,64 @@ +//go:build amd64 && !appengine && !noasm && gc +// +build amd64,!appengine,!noasm,gc + +package zstd + +import ( + "fmt" +) + +type buildDtableAsmContext struct { + // inputs + stateTable *uint16 + norm *int16 + dt *uint64 + + // outputs --- set by the procedure in the case of error; + // for interpretation please see the error handling part below + errParam1 uint64 + errParam2 uint64 +} + +// buildDtable_asm is an x86 assembly implementation of fseDecoder.buildDtable. +// Function returns non-zero exit code on error. +// go:noescape +func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int + +// please keep in sync with _generate/gen_fse.go +const ( + errorCorruptedNormalizedCounter = 1 + errorNewStateTooBig = 2 + errorNewStateNoBits = 3 +) + +// buildDtable will build the decoding table. +func (s *fseDecoder) buildDtable() error { + ctx := buildDtableAsmContext{ + stateTable: &s.stateTable[0], + norm: &s.norm[0], + dt: (*uint64)(&s.dt[0]), + } + code := buildDtable_asm(s, &ctx) + + if code != 0 { + switch code { + case errorCorruptedNormalizedCounter: + position := ctx.errParam1 + return fmt.Errorf("corrupted input (position=%d, expected 0)", position) + + case errorNewStateTooBig: + newState := decSymbol(ctx.errParam1) + size := ctx.errParam2 + return fmt.Errorf("newState (%d) outside table size (%d)", newState, size) + + case errorNewStateNoBits: + newState := decSymbol(ctx.errParam1) + oldState := decSymbol(ctx.errParam2) + return fmt.Errorf("newState (%d) == oldState (%d) and no bits", newState, oldState) + + default: + return fmt.Errorf("buildDtable_asm returned unhandled nonzero code = %d", code) + } + } + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s new file mode 100644 index 000000000..bcde39869 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_amd64.s @@ -0,0 +1,126 @@ +// Code generated by command: go run gen_fse.go -out ../fse_decoder_amd64.s -pkg=zstd. DO NOT EDIT. + +//go:build !appengine && !noasm && gc && !noasm + +// func buildDtable_asm(s *fseDecoder, ctx *buildDtableAsmContext) int +TEXT ·buildDtable_asm(SB), $0-24 + MOVQ ctx+8(FP), CX + MOVQ s+0(FP), DI + + // Load values + MOVBQZX 4098(DI), DX + XORQ AX, AX + BTSQ DX, AX + MOVQ (CX), BX + MOVQ 16(CX), SI + LEAQ -1(AX), R8 + MOVQ 8(CX), CX + MOVWQZX 4096(DI), DI + + // End load values + // Init, lay down lowprob symbols + XORQ R9, R9 + JMP init_main_loop_condition + +init_main_loop: + MOVWQSX (CX)(R9*2), R10 + CMPW R10, $-1 + JNE do_not_update_high_threshold + MOVB R9, 1(SI)(R8*8) + DECQ R8 + MOVQ $0x0000000000000001, R10 + +do_not_update_high_threshold: + MOVW R10, (BX)(R9*2) + INCQ R9 + +init_main_loop_condition: + CMPQ R9, DI + JL init_main_loop + + // Spread symbols + // Calculate table step + MOVQ AX, R9 + SHRQ $0x01, R9 + MOVQ AX, R10 + SHRQ $0x03, R10 + LEAQ 3(R9)(R10*1), R9 + + // Fill add bits values + LEAQ -1(AX), R10 + XORQ R11, R11 + XORQ R12, R12 + JMP spread_main_loop_condition + +spread_main_loop: + XORQ R13, R13 + MOVWQSX (CX)(R12*2), R14 + JMP spread_inner_loop_condition + +spread_inner_loop: + MOVB R12, 1(SI)(R11*8) + +adjust_position: + ADDQ R9, R11 + ANDQ R10, R11 + CMPQ R11, R8 + JG adjust_position + INCQ R13 + +spread_inner_loop_condition: + CMPQ R13, R14 + JL spread_inner_loop + INCQ R12 + +spread_main_loop_condition: + CMPQ R12, DI + JL spread_main_loop + TESTQ R11, R11 + JZ spread_check_ok + MOVQ ctx+8(FP), AX + MOVQ R11, 24(AX) + MOVQ $+1, ret+16(FP) + RET + +spread_check_ok: + // Build Decoding table + XORQ DI, DI + +build_table_main_table: + MOVBQZX 1(SI)(DI*8), CX + MOVWQZX (BX)(CX*2), R8 + LEAQ 1(R8), R9 + MOVW R9, (BX)(CX*2) + MOVQ R8, R9 + BSRQ R9, R9 + MOVQ DX, CX + SUBQ R9, CX + SHLQ CL, R8 + SUBQ AX, R8 + MOVB CL, (SI)(DI*8) + MOVW R8, 2(SI)(DI*8) + CMPQ R8, AX + JLE build_table_check1_ok + MOVQ ctx+8(FP), CX + MOVQ R8, 24(CX) + MOVQ AX, 32(CX) + MOVQ $+2, ret+16(FP) + RET + +build_table_check1_ok: + TESTB CL, CL + JNZ build_table_check2_ok + CMPW R8, DI + JNE build_table_check2_ok + MOVQ ctx+8(FP), AX + MOVQ R8, 24(AX) + MOVQ DI, 32(AX) + MOVQ $+3, ret+16(FP) + RET + +build_table_check2_ok: + INCQ DI + CMPQ DI, AX + JL build_table_main_table + MOVQ $+0, ret+16(FP) + RET diff --git a/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go new file mode 100644 index 000000000..332e51fe4 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/fse_decoder_generic.go @@ -0,0 +1,72 @@ +//go:build !amd64 || appengine || !gc || noasm +// +build !amd64 appengine !gc noasm + +package zstd + +import ( + "errors" + "fmt" +) + +// buildDtable will build the decoding table. +func (s *fseDecoder) buildDtable() error { + tableSize := uint32(1 << s.actualTableLog) + highThreshold := tableSize - 1 + symbolNext := s.stateTable[:256] + + // Init, lay down lowprob symbols + { + for i, v := range s.norm[:s.symbolLen] { + if v == -1 { + s.dt[highThreshold].setAddBits(uint8(i)) + highThreshold-- + symbolNext[i] = 1 + } else { + symbolNext[i] = uint16(v) + } + } + } + + // Spread symbols + { + tableMask := tableSize - 1 + step := tableStep(tableSize) + position := uint32(0) + for ss, v := range s.norm[:s.symbolLen] { + for i := 0; i < int(v); i++ { + s.dt[position].setAddBits(uint8(ss)) + position = (position + step) & tableMask + for position > highThreshold { + // lowprob area + position = (position + step) & tableMask + } + } + } + if position != 0 { + // position must reach all cells once, otherwise normalizedCounter is incorrect + return errors.New("corrupted input (position != 0)") + } + } + + // Build Decoding table + { + tableSize := uint16(1 << s.actualTableLog) + for u, v := range s.dt[:tableSize] { + symbol := v.addBits() + nextState := symbolNext[symbol] + symbolNext[symbol] = nextState + 1 + nBits := s.actualTableLog - byte(highBits(uint32(nextState))) + s.dt[u&maxTableMask].setNBits(nBits) + newState := (nextState << nBits) - tableSize + if newState > tableSize { + return fmt.Errorf("newState (%d) outside table size (%d)", newState, tableSize) + } + if newState == uint16(u) && nBits == 0 { + // Seems weird that this is possible with nbits > 0. + return fmt.Errorf("newState (%d) == oldState (%d) and no bits", newState, u) + } + s.dt[u&maxTableMask].setNewState(newState) + } + } + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go index 5442061b1..ab26326a8 100644 --- a/vendor/github.com/klauspost/compress/zstd/fse_encoder.go +++ b/vendor/github.com/klauspost/compress/zstd/fse_encoder.go @@ -76,21 +76,6 @@ func (s *fseEncoder) HistogramFinished(maxSymbol uint8, maxCount int) { s.clearCount = maxCount != 0 } -// prepare will prepare and allocate scratch tables used for both compression and decompression. -func (s *fseEncoder) prepare() (*fseEncoder, error) { - if s == nil { - s = &fseEncoder{} - } - s.useRLE = false - if s.clearCount && s.maxCount == 0 { - for i := range s.count { - s.count[i] = 0 - } - s.clearCount = false - } - return s, nil -} - // allocCtable will allocate tables needed for compression. // If existing tables a re big enough, they are simply re-used. func (s *fseEncoder) allocCtable() { @@ -709,14 +694,6 @@ func (c *cState) init(bw *bitWriter, ct *cTable, first symbolTransform) { c.state = c.stateTable[lu] } -// encode the output symbol provided and write it to the bitstream. -func (c *cState) encode(symbolTT symbolTransform) { - nbBitsOut := (uint32(c.state) + symbolTT.deltaNbBits) >> 16 - dstState := int32(c.state>>(nbBitsOut&15)) + int32(symbolTT.deltaFindState) - c.bw.addBits16NC(c.state, uint8(nbBitsOut)) - c.state = c.stateTable[dstState] -} - // flush will write the tablelog to the output and flush the remaining full bytes. func (c *cState) flush(tableLog uint8) { c.bw.flush32() diff --git a/vendor/github.com/klauspost/compress/zstd/fuzz.go b/vendor/github.com/klauspost/compress/zstd/fuzz.go deleted file mode 100644 index 7f2210e05..000000000 --- a/vendor/github.com/klauspost/compress/zstd/fuzz.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build ignorecrc -// +build ignorecrc - -// Copyright 2019+ Klaus Post. All rights reserved. -// License information can be found in the LICENSE file. -// Based on work by Yann Collet, released under BSD License. - -package zstd - -// ignoreCRC can be used for fuzz testing to ignore CRC values... -const ignoreCRC = true diff --git a/vendor/github.com/klauspost/compress/zstd/fuzz_none.go b/vendor/github.com/klauspost/compress/zstd/fuzz_none.go deleted file mode 100644 index 6811c68a8..000000000 --- a/vendor/github.com/klauspost/compress/zstd/fuzz_none.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build !ignorecrc -// +build !ignorecrc - -// Copyright 2019+ Klaus Post. All rights reserved. -// License information can be found in the LICENSE file. -// Based on work by Yann Collet, released under BSD License. - -package zstd - -// ignoreCRC can be used for fuzz testing to ignore CRC values... -const ignoreCRC = false diff --git a/vendor/github.com/klauspost/compress/zstd/hash.go b/vendor/github.com/klauspost/compress/zstd/hash.go index cf33f29a1..5d73c21eb 100644 --- a/vendor/github.com/klauspost/compress/zstd/hash.go +++ b/vendor/github.com/klauspost/compress/zstd/hash.go @@ -33,9 +33,3 @@ func hashLen(u uint64, length, mls uint8) uint32 { return (uint32(u) * prime4bytes) >> (32 - length) } } - -// hash3 returns the hash of the lower 3 bytes of u to fit in a hash table with h bits. -// Preferably h should be a constant and should always be <32. -func hash3(u uint32, h uint8) uint32 { - return ((u << (32 - 24)) * prime3bytes) >> ((32 - h) & 31) -} diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec.go b/vendor/github.com/klauspost/compress/zstd/seqdec.go index 819f1461b..df0447203 100644 --- a/vendor/github.com/klauspost/compress/zstd/seqdec.go +++ b/vendor/github.com/klauspost/compress/zstd/seqdec.go @@ -73,6 +73,7 @@ type sequenceDecs struct { seqSize int windowSize int maxBits uint8 + maxSyncLen uint64 } // initialize all 3 decoders from the stream input. @@ -98,153 +99,13 @@ func (s *sequenceDecs) initialize(br *bitReader, hist *history, out []byte) erro return nil } -// decode sequences from the stream with the provided history. -func (s *sequenceDecs) decode(seqs []seqVals) error { - br := s.br - - // Grab full sizes tables, to avoid bounds checks. - llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize] - llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state - s.seqSize = 0 - litRemain := len(s.literals) - maxBlockSize := maxCompressedBlockSize - if s.windowSize < maxBlockSize { - maxBlockSize = s.windowSize - } - for i := range seqs { - var ll, mo, ml int - if br.off > 4+((maxOffsetBits+16+16)>>3) { - // inlined function: - // ll, mo, ml = s.nextFast(br, llState, mlState, ofState) - - // Final will not read from stream. - var llB, mlB, moB uint8 - ll, llB = llState.final() - ml, mlB = mlState.final() - mo, moB = ofState.final() - - // extra bits are stored in reverse order. - br.fillFast() - mo += br.getBits(moB) - if s.maxBits > 32 { - br.fillFast() - } - ml += br.getBits(mlB) - ll += br.getBits(llB) - - if moB > 1 { - s.prevOffset[2] = s.prevOffset[1] - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = mo - } else { - // mo = s.adjustOffset(mo, ll, moB) - // Inlined for rather big speedup - if ll == 0 { - // There is an exception though, when current sequence's literals_length = 0. - // In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2, - // an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte. - mo++ - } - - if mo == 0 { - mo = s.prevOffset[0] - } else { - var temp int - if mo == 3 { - temp = s.prevOffset[0] - 1 - } else { - temp = s.prevOffset[mo] - } - - if temp == 0 { - // 0 is not valid; input is corrupted; force offset to 1 - println("WARNING: temp was 0") - temp = 1 - } - - if mo != 1 { - s.prevOffset[2] = s.prevOffset[1] - } - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = temp - mo = temp - } - } - br.fillFast() - } else { - if br.overread() { - if debugDecoder { - printf("reading sequence %d, exceeded available data\n", i) - } - return io.ErrUnexpectedEOF - } - ll, mo, ml = s.next(br, llState, mlState, ofState) - br.fill() - } - - if debugSequences { - println("Seq", i, "Litlen:", ll, "mo:", mo, "(abs) ml:", ml) - } - // Evaluate. - // We might be doing this async, so do it early. - if mo == 0 && ml > 0 { - return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) - } - if ml > maxMatchLen { - return fmt.Errorf("match len (%d) bigger than max allowed length", ml) - } - s.seqSize += ll + ml - if s.seqSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) - } - litRemain -= ll - if litRemain < 0 { - return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, litRemain+ll) - } - seqs[i] = seqVals{ - ll: ll, - ml: ml, - mo: mo, - } - if i == len(seqs)-1 { - // This is the last sequence, so we shouldn't update state. - break - } - - // Manually inlined, ~ 5-20% faster - // Update all 3 states at once. Approx 20% faster. - nBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits() - if nBits == 0 { - llState = llTable[llState.newState()&maxTableMask] - mlState = mlTable[mlState.newState()&maxTableMask] - ofState = ofTable[ofState.newState()&maxTableMask] - } else { - bits := br.get32BitsFast(nBits) - lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31)) - llState = llTable[(llState.newState()+lowBits)&maxTableMask] - - lowBits = uint16(bits >> (ofState.nbBits() & 31)) - lowBits &= bitMask[mlState.nbBits()&15] - mlState = mlTable[(mlState.newState()+lowBits)&maxTableMask] - - lowBits = uint16(bits) & bitMask[ofState.nbBits()&15] - ofState = ofTable[(ofState.newState()+lowBits)&maxTableMask] - } - } - s.seqSize += litRemain - if s.seqSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) - } - err := br.close() - if err != nil { - printf("Closing sequences: %v, %+v\n", err, *br) - } - return err -} - // execute will execute the decoded sequence with the provided history. // The sequence must be evaluated before being sent. func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { + if len(s.dict) == 0 { + return s.executeSimple(seqs, hist) + } + // Ensure we have enough output size... if len(s.out)+s.seqSize > cap(s.out) { addBytes := s.seqSize + len(s.out) @@ -327,6 +188,7 @@ func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { } } } + // Add final literals copy(out[t:], s.literals) if debugDecoder { @@ -341,14 +203,18 @@ func (s *sequenceDecs) execute(seqs []seqVals, hist []byte) error { } // decode sequences from the stream with the provided history. -func (s *sequenceDecs) decodeSync(history *history) error { +func (s *sequenceDecs) decodeSync(hist []byte) error { + supported, err := s.decodeSyncSimple(hist) + if supported { + return err + } + br := s.br seqs := s.nSeqs startSize := len(s.out) // Grab full sizes tables, to avoid bounds checks. llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize] llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state - hist := history.b[history.ignoreBuffer:] out := s.out maxBlockSize := maxCompressedBlockSize if s.windowSize < maxBlockSize { @@ -433,7 +299,7 @@ func (s *sequenceDecs) decodeSync(history *history) error { } size := ll + ml + len(out) if size-startSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", size, maxBlockSize) + return fmt.Errorf("output (%d) bigger than max block size (%d)", size-startSize, maxBlockSize) } if size > cap(out) { // Not enough size, which can happen under high volume block streaming conditions @@ -463,13 +329,13 @@ func (s *sequenceDecs) decodeSync(history *history) error { if mo > len(out)+len(hist) || mo > s.windowSize { if len(s.dict) == 0 { - return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)) + return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)-startSize) } // we may be in dictionary. dictO := len(s.dict) - (mo - (len(out) + len(hist))) if dictO < 0 || dictO >= len(s.dict) { - return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)) + return fmt.Errorf("match offset (%d) bigger than current history (%d)", mo, len(out)+len(hist)-startSize) } end := dictO + ml if end > len(s.dict) { @@ -530,6 +396,7 @@ func (s *sequenceDecs) decodeSync(history *history) error { ofState = ofTable[ofState.newState()&maxTableMask] } else { bits := br.get32BitsFast(nBits) + lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31)) llState = llTable[(llState.newState()+lowBits)&maxTableMask] @@ -543,8 +410,8 @@ func (s *sequenceDecs) decodeSync(history *history) error { } // Check if space for literals - if len(s.literals)+len(s.out)-startSize > maxBlockSize { - return fmt.Errorf("output (%d) bigger than max block size (%d)", len(s.out), maxBlockSize) + if size := len(s.literals) + len(s.out) - startSize; size > maxBlockSize { + return fmt.Errorf("output (%d) bigger than max block size (%d)", size, maxBlockSize) } // Add final literals @@ -552,16 +419,6 @@ func (s *sequenceDecs) decodeSync(history *history) error { return br.close() } -// update states, at least 27 bits must be available. -func (s *sequenceDecs) update(br *bitReader) { - // Max 8 bits - s.litLengths.state.next(br) - // Max 9 bits - s.matchLengths.state.next(br) - // Max 8 bits - s.offsets.state.next(br) -} - var bitMask [16]uint16 func init() { @@ -570,87 +427,6 @@ func init() { } } -// update states, at least 27 bits must be available. -func (s *sequenceDecs) updateAlt(br *bitReader) { - // Update all 3 states at once. Approx 20% faster. - a, b, c := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state - - nBits := a.nbBits() + b.nbBits() + c.nbBits() - if nBits == 0 { - s.litLengths.state.state = s.litLengths.state.dt[a.newState()] - s.matchLengths.state.state = s.matchLengths.state.dt[b.newState()] - s.offsets.state.state = s.offsets.state.dt[c.newState()] - return - } - bits := br.get32BitsFast(nBits) - lowBits := uint16(bits >> ((c.nbBits() + b.nbBits()) & 31)) - s.litLengths.state.state = s.litLengths.state.dt[a.newState()+lowBits] - - lowBits = uint16(bits >> (c.nbBits() & 31)) - lowBits &= bitMask[b.nbBits()&15] - s.matchLengths.state.state = s.matchLengths.state.dt[b.newState()+lowBits] - - lowBits = uint16(bits) & bitMask[c.nbBits()&15] - s.offsets.state.state = s.offsets.state.dt[c.newState()+lowBits] -} - -// nextFast will return new states when there are at least 4 unused bytes left on the stream when done. -func (s *sequenceDecs) nextFast(br *bitReader, llState, mlState, ofState decSymbol) (ll, mo, ml int) { - // Final will not read from stream. - ll, llB := llState.final() - ml, mlB := mlState.final() - mo, moB := ofState.final() - - // extra bits are stored in reverse order. - br.fillFast() - mo += br.getBits(moB) - if s.maxBits > 32 { - br.fillFast() - } - ml += br.getBits(mlB) - ll += br.getBits(llB) - - if moB > 1 { - s.prevOffset[2] = s.prevOffset[1] - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = mo - return - } - // mo = s.adjustOffset(mo, ll, moB) - // Inlined for rather big speedup - if ll == 0 { - // There is an exception though, when current sequence's literals_length = 0. - // In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2, - // an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte. - mo++ - } - - if mo == 0 { - mo = s.prevOffset[0] - return - } - var temp int - if mo == 3 { - temp = s.prevOffset[0] - 1 - } else { - temp = s.prevOffset[mo] - } - - if temp == 0 { - // 0 is not valid; input is corrupted; force offset to 1 - println("temp was 0") - temp = 1 - } - - if mo != 1 { - s.prevOffset[2] = s.prevOffset[1] - } - s.prevOffset[1] = s.prevOffset[0] - s.prevOffset[0] = temp - mo = temp - return -} - func (s *sequenceDecs) next(br *bitReader, llState, mlState, ofState decSymbol) (ll, mo, ml int) { // Final will not read from stream. ll, llB := llState.final() diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go new file mode 100644 index 000000000..1c704d30c --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.go @@ -0,0 +1,378 @@ +//go:build amd64 && !appengine && !noasm && gc +// +build amd64,!appengine,!noasm,gc + +package zstd + +import ( + "fmt" + + "github.com/klauspost/compress/internal/cpuinfo" +) + +type decodeSyncAsmContext struct { + llTable []decSymbol + mlTable []decSymbol + ofTable []decSymbol + llState uint64 + mlState uint64 + ofState uint64 + iteration int + litRemain int + out []byte + outPosition int + literals []byte + litPosition int + history []byte + windowSize int + ll int // set on error (not for all errors, please refer to _generate/gen.go) + ml int // set on error (not for all errors, please refer to _generate/gen.go) + mo int // set on error (not for all errors, please refer to _generate/gen.go) +} + +// sequenceDecs_decodeSync_amd64 implements the main loop of sequenceDecs.decodeSync in x86 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// sequenceDecs_decodeSync_bmi2 implements the main loop of sequenceDecs.decodeSync in x86 asm with BMI2 extensions. +// +//go:noescape +func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// sequenceDecs_decodeSync_safe_amd64 does the same as above, but does not write more than output buffer. +// +//go:noescape +func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// sequenceDecs_decodeSync_safe_bmi2 does the same as above, but does not write more than output buffer. +// +//go:noescape +func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int + +// decode sequences from the stream with the provided history but without a dictionary. +func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { + if len(s.dict) > 0 { + return false, nil + } + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSize { + return false, nil + } + + // FIXME: Using unsafe memory copies leads to rare, random crashes + // with fuzz testing. It is therefore disabled for now. + const useSafe = true + /* + useSafe := false + if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc { + useSafe = true + } + if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) { + useSafe = true + } + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + useSafe = true + } + */ + + br := s.br + + maxBlockSize := maxCompressedBlockSize + if s.windowSize < maxBlockSize { + maxBlockSize = s.windowSize + } + + ctx := decodeSyncAsmContext{ + llTable: s.litLengths.fse.dt[:maxTablesize], + mlTable: s.matchLengths.fse.dt[:maxTablesize], + ofTable: s.offsets.fse.dt[:maxTablesize], + llState: uint64(s.litLengths.state.state), + mlState: uint64(s.matchLengths.state.state), + ofState: uint64(s.offsets.state.state), + iteration: s.nSeqs - 1, + litRemain: len(s.literals), + out: s.out, + outPosition: len(s.out), + literals: s.literals, + windowSize: s.windowSize, + history: hist, + } + + s.seqSize = 0 + startSize := len(s.out) + + var errCode int + if cpuinfo.HasBMI2() { + if useSafe { + errCode = sequenceDecs_decodeSync_safe_bmi2(s, br, &ctx) + } else { + errCode = sequenceDecs_decodeSync_bmi2(s, br, &ctx) + } + } else { + if useSafe { + errCode = sequenceDecs_decodeSync_safe_amd64(s, br, &ctx) + } else { + errCode = sequenceDecs_decodeSync_amd64(s, br, &ctx) + } + } + switch errCode { + case noError: + break + + case errorMatchLenOfsMismatch: + return true, fmt.Errorf("zero matchoff and matchlen (%d) > 0", ctx.ml) + + case errorMatchLenTooBig: + return true, fmt.Errorf("match len (%d) bigger than max allowed length", ctx.ml) + + case errorMatchOffTooBig: + return true, fmt.Errorf("match offset (%d) bigger than current history (%d)", + ctx.mo, ctx.outPosition+len(hist)-startSize) + + case errorNotEnoughLiterals: + return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", + ctx.ll, ctx.litRemain+ctx.ll) + + case errorNotEnoughSpace: + size := ctx.outPosition + ctx.ll + ctx.ml + if debugDecoder { + println("msl:", s.maxSyncLen, "cap", cap(s.out), "bef:", startSize, "sz:", size-startSize, "mbs:", maxBlockSize, "outsz:", cap(s.out)-startSize) + } + return true, fmt.Errorf("output (%d) bigger than max block size (%d)", size-startSize, maxBlockSize) + + default: + return true, fmt.Errorf("sequenceDecs_decode returned erronous code %d", errCode) + } + + s.seqSize += ctx.litRemain + if s.seqSize > maxBlockSize { + return true, fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + return true, err + } + + s.literals = s.literals[ctx.litPosition:] + t := ctx.outPosition + s.out = s.out[:t] + + // Add final literals + s.out = append(s.out, s.literals...) + if debugDecoder { + t += len(s.literals) + if t != len(s.out) { + panic(fmt.Errorf("length mismatch, want %d, got %d", len(s.out), t)) + } + } + + return true, nil +} + +// -------------------------------------------------------------------------------- + +type decodeAsmContext struct { + llTable []decSymbol + mlTable []decSymbol + ofTable []decSymbol + llState uint64 + mlState uint64 + ofState uint64 + iteration int + seqs []seqVals + litRemain int +} + +const noError = 0 + +// error reported when mo == 0 && ml > 0 +const errorMatchLenOfsMismatch = 1 + +// error reported when ml > maxMatchLen +const errorMatchLenTooBig = 2 + +// error reported when mo > available history or mo > s.windowSize +const errorMatchOffTooBig = 3 + +// error reported when the sum of literal lengths exeeceds the literal buffer size +const errorNotEnoughLiterals = 4 + +// error reported when capacity of `out` is too small +const errorNotEnoughSpace = 5 + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// +//go:noescape +func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm with BMI2 extensions. +// +//go:noescape +func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int + +// decode sequences from the stream without the provided history. +func (s *sequenceDecs) decode(seqs []seqVals) error { + br := s.br + + maxBlockSize := maxCompressedBlockSize + if s.windowSize < maxBlockSize { + maxBlockSize = s.windowSize + } + + ctx := decodeAsmContext{ + llTable: s.litLengths.fse.dt[:maxTablesize], + mlTable: s.matchLengths.fse.dt[:maxTablesize], + ofTable: s.offsets.fse.dt[:maxTablesize], + llState: uint64(s.litLengths.state.state), + mlState: uint64(s.matchLengths.state.state), + ofState: uint64(s.offsets.state.state), + seqs: seqs, + iteration: len(seqs) - 1, + litRemain: len(s.literals), + } + + s.seqSize = 0 + lte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56 + var errCode int + if cpuinfo.HasBMI2() { + if lte56bits { + errCode = sequenceDecs_decode_56_bmi2(s, br, &ctx) + } else { + errCode = sequenceDecs_decode_bmi2(s, br, &ctx) + } + } else { + if lte56bits { + errCode = sequenceDecs_decode_56_amd64(s, br, &ctx) + } else { + errCode = sequenceDecs_decode_amd64(s, br, &ctx) + } + } + if errCode != 0 { + i := len(seqs) - ctx.iteration - 1 + switch errCode { + case errorMatchLenOfsMismatch: + ml := ctx.seqs[i].ml + return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) + + case errorMatchLenTooBig: + ml := ctx.seqs[i].ml + return fmt.Errorf("match len (%d) bigger than max allowed length", ml) + + case errorNotEnoughLiterals: + ll := ctx.seqs[i].ll + return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, ctx.litRemain+ll) + } + + return fmt.Errorf("sequenceDecs_decode_amd64 returned erronous code %d", errCode) + } + + if ctx.litRemain < 0 { + return fmt.Errorf("literal count is too big: total available %d, total requested %d", + len(s.literals), len(s.literals)-ctx.litRemain) + } + + s.seqSize += ctx.litRemain + if s.seqSize > maxBlockSize { + return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + } + return err +} + +// -------------------------------------------------------------------------------- + +type executeAsmContext struct { + seqs []seqVals + seqIndex int + out []byte + history []byte + literals []byte + outPosition int + litPosition int + windowSize int +} + +// sequenceDecs_executeSimple_amd64 implements the main loop of sequenceDecs.executeSimple in x86 asm. +// +// Returns false if a match offset is too big. +// +// Please refer to seqdec_generic.go for the reference implementation. +// +//go:noescape +func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool + +// Same as above, but with safe memcopies +// +//go:noescape +func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool + +// executeSimple handles cases when dictionary is not used. +func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error { + // Ensure we have enough output size... + if len(s.out)+s.seqSize+compressedBlockOverAlloc > cap(s.out) { + addBytes := s.seqSize + len(s.out) + compressedBlockOverAlloc + s.out = append(s.out, make([]byte, addBytes)...) + s.out = s.out[:len(s.out)-addBytes] + } + + if debugDecoder { + printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize) + } + + var t = len(s.out) + out := s.out[:t+s.seqSize] + + ctx := executeAsmContext{ + seqs: seqs, + seqIndex: 0, + out: out, + history: hist, + outPosition: t, + litPosition: 0, + literals: s.literals, + windowSize: s.windowSize, + } + var ok bool + if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc { + ok = sequenceDecs_executeSimple_safe_amd64(&ctx) + } else { + ok = sequenceDecs_executeSimple_amd64(&ctx) + } + if !ok { + return fmt.Errorf("match offset (%d) bigger than current history (%d)", + seqs[ctx.seqIndex].mo, ctx.outPosition+len(hist)) + } + s.literals = s.literals[ctx.litPosition:] + t = ctx.outPosition + + // Add final literals + copy(out[t:], s.literals) + if debugDecoder { + t += len(s.literals) + if t != len(out) { + panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize)) + } + } + s.out = out + + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s new file mode 100644 index 000000000..52e5703c2 --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_amd64.s @@ -0,0 +1,4099 @@ +// Code generated by command: go run gen.go -out ../seqdec_amd64.s -pkg=zstd. DO NOT EDIT. + +//go:build !appengine && !noasm && gc && !noasm + +// func sequenceDecs_decode_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: CMOV +TEXT ·sequenceDecs_decode_amd64(SB), $8-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + MOVQ 104(AX), R10 + MOVQ s+0(FP), AX + MOVQ 144(AX), R11 + MOVQ 152(AX), R12 + MOVQ 160(AX), R13 + +sequenceDecs_decode_amd64_main_loop: + MOVQ (SP), R14 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decode_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R14 + MOVQ (R14), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decode_amd64_fill_end + +sequenceDecs_decode_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decode_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decode_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R14 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R14), AX + ORQ AX, DX + JMP sequenceDecs_decode_amd64_fill_byte_by_byte + +sequenceDecs_decode_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_of_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_amd64_of_update_zero: + MOVQ AX, 16(R10) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_amd64_ml_update_zero: + MOVQ AX, 8(R10) + + // Fill bitreader to have enough for the remaining + CMPQ SI, $0x08 + JL sequenceDecs_decode_amd64_fill_2_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R14 + MOVQ (R14), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decode_amd64_fill_2_end + +sequenceDecs_decode_amd64_fill_2_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decode_amd64_fill_2_end + CMPQ BX, $0x07 + JLE sequenceDecs_decode_amd64_fill_2_end + SHLQ $0x08, DX + SUBQ $0x01, R14 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R14), AX + ORQ AX, DX + JMP sequenceDecs_decode_amd64_fill_2_byte_by_byte + +sequenceDecs_decode_amd64_fill_2_end: + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_amd64_ll_update_zero: + MOVQ AX, (R10) + + // Fill bitreader for state updates + MOVQ R14, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R14 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R14 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R14 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decode_amd64_skip_update: + // Adjust offset + MOVQ 16(R10), CX + CMPQ AX, $0x01 + JBE sequenceDecs_decode_amd64_adjust_offsetB_1_or_0 + MOVQ R12, R13 + MOVQ R11, R12 + MOVQ CX, R11 + JMP sequenceDecs_decode_amd64_after_adjust + +sequenceDecs_decode_amd64_adjust_offsetB_1_or_0: + CMPQ (R10), $0x00000000 + JNE sequenceDecs_decode_amd64_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_amd64_adjust_offset_nonzero + +sequenceDecs_decode_amd64_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_amd64_adjust_offset_nonzero + MOVQ R11, CX + JMP sequenceDecs_decode_amd64_after_adjust + +sequenceDecs_decode_amd64_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_amd64_adjust_zero + JEQ sequenceDecs_decode_amd64_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_amd64_adjust_three + JMP sequenceDecs_decode_amd64_adjust_two + +sequenceDecs_decode_amd64_adjust_zero: + MOVQ R11, AX + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_one: + MOVQ R12, AX + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_two: + MOVQ R13, AX + JMP sequenceDecs_decode_amd64_adjust_test_temp_valid + +sequenceDecs_decode_amd64_adjust_three: + LEAQ -1(R11), AX + +sequenceDecs_decode_amd64_adjust_test_temp_valid: + TESTQ AX, AX + JNZ sequenceDecs_decode_amd64_adjust_temp_valid + MOVQ $0x00000001, AX + +sequenceDecs_decode_amd64_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R12, R13 + MOVQ R11, R12 + MOVQ AX, R11 + MOVQ AX, CX + +sequenceDecs_decode_amd64_after_adjust: + MOVQ CX, 16(R10) + + // Check values + MOVQ 8(R10), AX + MOVQ (R10), R14 + LEAQ (AX)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decode_amd64_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decode_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decode_amd64_match_len_ofs_ok: + ADDQ $0x18, R10 + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decode_amd64_main_loop + MOVQ s+0(FP), AX + MOVQ R11, 144(AX) + MOVQ R12, 152(AX) + MOVQ R13, 160(AX) + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_amd64_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_amd64_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: CMOV +TEXT ·sequenceDecs_decode_56_amd64(SB), $8-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + MOVQ 104(AX), R10 + MOVQ s+0(FP), AX + MOVQ 144(AX), R11 + MOVQ 152(AX), R12 + MOVQ 160(AX), R13 + +sequenceDecs_decode_56_amd64_main_loop: + MOVQ (SP), R14 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decode_56_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R14 + MOVQ (R14), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decode_56_amd64_fill_end + +sequenceDecs_decode_56_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decode_56_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decode_56_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R14 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R14), AX + ORQ AX, DX + JMP sequenceDecs_decode_56_amd64_fill_byte_by_byte + +sequenceDecs_decode_56_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_of_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_56_amd64_of_update_zero: + MOVQ AX, 16(R10) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_56_amd64_ml_update_zero: + MOVQ AX, 8(R10) + + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R15 + SHLQ CL, R15 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decode_56_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decode_56_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decode_56_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R15 + ADDQ R15, AX + +sequenceDecs_decode_56_amd64_ll_update_zero: + MOVQ AX, (R10) + + // Fill bitreader for state updates + MOVQ R14, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_56_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R14 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R14 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R14 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R14*1), CX + MOVQ DX, R15 + MOVQ CX, BX + ROLQ CL, R15 + MOVL $0x00000001, BP + MOVB R14, CL + SHLL CL, BP + DECL BP + ANDQ BP, R15 + ADDQ R15, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decode_56_amd64_skip_update: + // Adjust offset + MOVQ 16(R10), CX + CMPQ AX, $0x01 + JBE sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0 + MOVQ R12, R13 + MOVQ R11, R12 + MOVQ CX, R11 + JMP sequenceDecs_decode_56_amd64_after_adjust + +sequenceDecs_decode_56_amd64_adjust_offsetB_1_or_0: + CMPQ (R10), $0x00000000 + JNE sequenceDecs_decode_56_amd64_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_56_amd64_adjust_offset_nonzero + +sequenceDecs_decode_56_amd64_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_56_amd64_adjust_offset_nonzero + MOVQ R11, CX + JMP sequenceDecs_decode_56_amd64_after_adjust + +sequenceDecs_decode_56_amd64_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_56_amd64_adjust_zero + JEQ sequenceDecs_decode_56_amd64_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_56_amd64_adjust_three + JMP sequenceDecs_decode_56_amd64_adjust_two + +sequenceDecs_decode_56_amd64_adjust_zero: + MOVQ R11, AX + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_one: + MOVQ R12, AX + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_two: + MOVQ R13, AX + JMP sequenceDecs_decode_56_amd64_adjust_test_temp_valid + +sequenceDecs_decode_56_amd64_adjust_three: + LEAQ -1(R11), AX + +sequenceDecs_decode_56_amd64_adjust_test_temp_valid: + TESTQ AX, AX + JNZ sequenceDecs_decode_56_amd64_adjust_temp_valid + MOVQ $0x00000001, AX + +sequenceDecs_decode_56_amd64_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R12, R13 + MOVQ R11, R12 + MOVQ AX, R11 + MOVQ AX, CX + +sequenceDecs_decode_56_amd64_after_adjust: + MOVQ CX, 16(R10) + + // Check values + MOVQ 8(R10), AX + MOVQ (R10), R14 + LEAQ (AX)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decode_56_amd64_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_56_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decode_56_amd64_match_len_ofs_ok: + ADDQ $0x18, R10 + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decode_56_amd64_main_loop + MOVQ s+0(FP), AX + MOVQ R11, 144(AX) + MOVQ R12, 152(AX) + MOVQ R13, 160(AX) + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_56_amd64_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_56_amd64_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: BMI, BMI2, CMOV +TEXT ·sequenceDecs_decode_bmi2(SB), $8-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + MOVQ 104(CX), R9 + MOVQ s+0(FP), CX + MOVQ 144(CX), R10 + MOVQ 152(CX), R11 + MOVQ 160(CX), R12 + +sequenceDecs_decode_bmi2_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decode_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R13 + MOVQ (R13), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decode_bmi2_fill_end + +sequenceDecs_decode_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decode_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decode_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R13 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R13), CX + ORQ CX, AX + JMP sequenceDecs_decode_bmi2_fill_byte_by_byte + +sequenceDecs_decode_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 16(R9) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 8(R9) + + // Fill bitreader to have enough for the remaining + CMPQ BX, $0x08 + JL sequenceDecs_decode_bmi2_fill_2_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R13 + MOVQ (R13), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decode_bmi2_fill_2_end + +sequenceDecs_decode_bmi2_fill_2_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decode_bmi2_fill_2_end + CMPQ DX, $0x07 + JLE sequenceDecs_decode_bmi2_fill_2_end + SHLQ $0x08, AX + SUBQ $0x01, R13 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R13), CX + ORQ CX, AX + JMP sequenceDecs_decode_bmi2_fill_2_byte_by_byte + +sequenceDecs_decode_bmi2_fill_2_end: + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, (R9) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_bmi2_skip_update + LEAQ (SI)(DI*1), R14 + ADDQ R8, R14 + MOVBQZX R14, R14 + LEAQ (DX)(R14*1), CX + MOVQ AX, R15 + MOVQ CX, DX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + + // Update Offset State + BZHIQ R8, R15, CX + SHRXQ R8, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R15, CX + SHRXQ DI, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R15, CX + MOVQ $0x00001010, R14 + BEXTRQ R14, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decode_bmi2_skip_update: + // Adjust offset + MOVQ 16(R9), CX + CMPQ R13, $0x01 + JBE sequenceDecs_decode_bmi2_adjust_offsetB_1_or_0 + MOVQ R11, R12 + MOVQ R10, R11 + MOVQ CX, R10 + JMP sequenceDecs_decode_bmi2_after_adjust + +sequenceDecs_decode_bmi2_adjust_offsetB_1_or_0: + CMPQ (R9), $0x00000000 + JNE sequenceDecs_decode_bmi2_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_bmi2_adjust_offset_nonzero + +sequenceDecs_decode_bmi2_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_bmi2_adjust_offset_nonzero + MOVQ R10, CX + JMP sequenceDecs_decode_bmi2_after_adjust + +sequenceDecs_decode_bmi2_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_bmi2_adjust_zero + JEQ sequenceDecs_decode_bmi2_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_bmi2_adjust_three + JMP sequenceDecs_decode_bmi2_adjust_two + +sequenceDecs_decode_bmi2_adjust_zero: + MOVQ R10, R13 + JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_bmi2_adjust_one: + MOVQ R11, R13 + JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_bmi2_adjust_two: + MOVQ R12, R13 + JMP sequenceDecs_decode_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_bmi2_adjust_three: + LEAQ -1(R10), R13 + +sequenceDecs_decode_bmi2_adjust_test_temp_valid: + TESTQ R13, R13 + JNZ sequenceDecs_decode_bmi2_adjust_temp_valid + MOVQ $0x00000001, R13 + +sequenceDecs_decode_bmi2_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R11, R12 + MOVQ R10, R11 + MOVQ R13, R10 + MOVQ R13, CX + +sequenceDecs_decode_bmi2_after_adjust: + MOVQ CX, 16(R9) + + // Check values + MOVQ 8(R9), R13 + MOVQ (R9), R14 + LEAQ (R13)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ R13, $0x00020002 + JA sequenceDecs_decode_bmi2_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_bmi2_match_len_ofs_ok + TESTQ R13, R13 + JNZ sequenceDecs_decode_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decode_bmi2_match_len_ofs_ok: + ADDQ $0x18, R9 + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decode_bmi2_main_loop + MOVQ s+0(FP), CX + MOVQ R10, 144(CX) + MOVQ R11, 152(CX) + MOVQ R12, 160(CX) + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_bmi2_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_bmi2_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int +// Requires: BMI, BMI2, CMOV +TEXT ·sequenceDecs_decode_56_bmi2(SB), $8-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + MOVQ 104(CX), R9 + MOVQ s+0(FP), CX + MOVQ 144(CX), R10 + MOVQ 152(CX), R11 + MOVQ 160(CX), R12 + +sequenceDecs_decode_56_bmi2_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decode_56_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R13 + MOVQ (R13), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decode_56_bmi2_fill_end + +sequenceDecs_decode_56_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decode_56_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decode_56_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R13 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R13), CX + ORQ CX, AX + JMP sequenceDecs_decode_56_bmi2_fill_byte_by_byte + +sequenceDecs_decode_56_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 16(R9) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, 8(R9) + + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R14 + MOVQ AX, R15 + LEAQ (DX)(R14*1), CX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R15, CX + MOVQ CX, (R9) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decode_56_bmi2_skip_update + LEAQ (SI)(DI*1), R14 + ADDQ R8, R14 + MOVBQZX R14, R14 + LEAQ (DX)(R14*1), CX + MOVQ AX, R15 + MOVQ CX, DX + ROLQ CL, R15 + BZHIQ R14, R15, R15 + + // Update Offset State + BZHIQ R8, R15, CX + SHRXQ R8, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R15, CX + SHRXQ DI, R15, R15 + MOVQ $0x00001010, R14 + BEXTRQ R14, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R15, CX + MOVQ $0x00001010, R14 + BEXTRQ R14, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decode_56_bmi2_skip_update: + // Adjust offset + MOVQ 16(R9), CX + CMPQ R13, $0x01 + JBE sequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0 + MOVQ R11, R12 + MOVQ R10, R11 + MOVQ CX, R10 + JMP sequenceDecs_decode_56_bmi2_after_adjust + +sequenceDecs_decode_56_bmi2_adjust_offsetB_1_or_0: + CMPQ (R9), $0x00000000 + JNE sequenceDecs_decode_56_bmi2_adjust_offset_maybezero + INCQ CX + JMP sequenceDecs_decode_56_bmi2_adjust_offset_nonzero + +sequenceDecs_decode_56_bmi2_adjust_offset_maybezero: + TESTQ CX, CX + JNZ sequenceDecs_decode_56_bmi2_adjust_offset_nonzero + MOVQ R10, CX + JMP sequenceDecs_decode_56_bmi2_after_adjust + +sequenceDecs_decode_56_bmi2_adjust_offset_nonzero: + CMPQ CX, $0x01 + JB sequenceDecs_decode_56_bmi2_adjust_zero + JEQ sequenceDecs_decode_56_bmi2_adjust_one + CMPQ CX, $0x02 + JA sequenceDecs_decode_56_bmi2_adjust_three + JMP sequenceDecs_decode_56_bmi2_adjust_two + +sequenceDecs_decode_56_bmi2_adjust_zero: + MOVQ R10, R13 + JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_56_bmi2_adjust_one: + MOVQ R11, R13 + JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_56_bmi2_adjust_two: + MOVQ R12, R13 + JMP sequenceDecs_decode_56_bmi2_adjust_test_temp_valid + +sequenceDecs_decode_56_bmi2_adjust_three: + LEAQ -1(R10), R13 + +sequenceDecs_decode_56_bmi2_adjust_test_temp_valid: + TESTQ R13, R13 + JNZ sequenceDecs_decode_56_bmi2_adjust_temp_valid + MOVQ $0x00000001, R13 + +sequenceDecs_decode_56_bmi2_adjust_temp_valid: + CMPQ CX, $0x01 + CMOVQNE R11, R12 + MOVQ R10, R11 + MOVQ R13, R10 + MOVQ R13, CX + +sequenceDecs_decode_56_bmi2_after_adjust: + MOVQ CX, 16(R9) + + // Check values + MOVQ 8(R9), R13 + MOVQ (R9), R14 + LEAQ (R13)(R14*1), R15 + MOVQ s+0(FP), BP + ADDQ R15, 256(BP) + MOVQ ctx+16(FP), R15 + SUBQ R14, 128(R15) + JS error_not_enough_literals + CMPQ R13, $0x00020002 + JA sequenceDecs_decode_56_bmi2_error_match_len_too_big + TESTQ CX, CX + JNZ sequenceDecs_decode_56_bmi2_match_len_ofs_ok + TESTQ R13, R13 + JNZ sequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decode_56_bmi2_match_len_ofs_ok: + ADDQ $0x18, R9 + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decode_56_bmi2_main_loop + MOVQ s+0(FP), CX + MOVQ R10, 144(CX) + MOVQ R11, 152(CX) + MOVQ R12, 160(CX) + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decode_56_bmi2_error_match_len_ofs_mismatch: + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decode_56_bmi2_error_match_len_too_big: + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool +// Requires: SSE +TEXT ·sequenceDecs_executeSimple_amd64(SB), $8-9 + MOVQ ctx+0(FP), R10 + MOVQ 8(R10), CX + TESTQ CX, CX + JZ empty_seqs + MOVQ (R10), AX + MOVQ 24(R10), DX + MOVQ 32(R10), BX + MOVQ 80(R10), SI + MOVQ 104(R10), DI + MOVQ 120(R10), R8 + MOVQ 56(R10), R9 + MOVQ 64(R10), R10 + ADDQ R10, R9 + + // seqsBase += 24 * seqIndex + LEAQ (DX)(DX*2), R11 + SHLQ $0x03, R11 + ADDQ R11, AX + + // outBase += outPosition + ADDQ DI, BX + +main_loop: + MOVQ (AX), R11 + MOVQ 16(AX), R12 + MOVQ 8(AX), R13 + + // Copy literals + TESTQ R11, R11 + JZ check_offset + XORQ R14, R14 + +copy_1: + MOVUPS (SI)(R14*1), X0 + MOVUPS X0, (BX)(R14*1) + ADDQ $0x10, R14 + CMPQ R14, R11 + JB copy_1 + ADDQ R11, SI + ADDQ R11, BX + ADDQ R11, DI + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + LEAQ (DI)(R10*1), R11 + CMPQ R12, R11 + JG error_match_off_too_big + CMPQ R12, R8 + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, R11 + SUBQ DI, R11 + JLS copy_match + MOVQ R9, R14 + SUBQ R11, R14 + CMPQ R13, R11 + JG copy_all_from_history + MOVQ R13, R11 + SUBQ $0x10, R11 + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R11 + JAE copy_4_loop + LEAQ 16(R14)(R11*1), R14 + LEAQ 16(BX)(R11*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), R11 + MOVB 2(R14), R12 + MOVW R11, (BX) + MOVB R12, 2(BX) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), R11 + MOVL -4(R14)(R13*1), R12 + MOVL R11, (BX) + MOVL R12, -4(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), R11 + MOVQ -8(R14)(R13*1), R12 + MOVQ R11, (BX) + MOVQ R12, -8(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + +copy_4_end: + ADDQ R13, DI + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + JMP loop_finished + +copy_all_from_history: + MOVQ R11, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(BX)(R15*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_5_end + +copy_5_small: + CMPQ R11, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ R11, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(R11*1), BP + MOVB R15, (BX) + MOVB BP, -1(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (BX) + MOVB BP, 2(BX) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(R11*1), BP + MOVL R15, (BX) + MOVL BP, -4(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(R11*1), BP + MOVQ R15, (BX) + MOVQ BP, -8(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + +copy_5_end: + ADDQ R11, DI + SUBQ R11, R13 + + // Copy match from the current buffer +copy_match: + MOVQ BX, R11 + SUBQ R12, R11 + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, DI + MOVQ BX, R12 + ADDQ R13, BX + +copy_2: + MOVUPS (R11), X0 + MOVUPS X0, (R12) + ADDQ $0x10, R11 + ADDQ $0x10, R12 + SUBQ $0x10, R13 + JHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, DI + +copy_slow_3: + MOVB (R11), R12 + MOVB R12, (BX) + INCQ R11 + INCQ BX + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + +loop_finished: + // Return value + MOVB $0x01, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + MOVQ 80(AX), CX + SUBQ CX, SI + MOVQ SI, 112(AX) + RET + +error_match_off_too_big: + // Return value + MOVB $0x00, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + MOVQ 80(AX), CX + SUBQ CX, SI + MOVQ SI, 112(AX) + RET + +empty_seqs: + // Return value + MOVB $0x01, ret+8(FP) + RET + +// func sequenceDecs_executeSimple_safe_amd64(ctx *executeAsmContext) bool +// Requires: SSE +TEXT ·sequenceDecs_executeSimple_safe_amd64(SB), $8-9 + MOVQ ctx+0(FP), R10 + MOVQ 8(R10), CX + TESTQ CX, CX + JZ empty_seqs + MOVQ (R10), AX + MOVQ 24(R10), DX + MOVQ 32(R10), BX + MOVQ 80(R10), SI + MOVQ 104(R10), DI + MOVQ 120(R10), R8 + MOVQ 56(R10), R9 + MOVQ 64(R10), R10 + ADDQ R10, R9 + + // seqsBase += 24 * seqIndex + LEAQ (DX)(DX*2), R11 + SHLQ $0x03, R11 + ADDQ R11, AX + + // outBase += outPosition + ADDQ DI, BX + +main_loop: + MOVQ (AX), R11 + MOVQ 16(AX), R12 + MOVQ 8(AX), R13 + + // Copy literals + TESTQ R11, R11 + JZ check_offset + MOVQ R11, R14 + SUBQ $0x10, R14 + JB copy_1_small + +copy_1_loop: + MOVUPS (SI), X0 + MOVUPS X0, (BX) + ADDQ $0x10, SI + ADDQ $0x10, BX + SUBQ $0x10, R14 + JAE copy_1_loop + LEAQ 16(SI)(R14*1), SI + LEAQ 16(BX)(R14*1), BX + MOVUPS -16(SI), X0 + MOVUPS X0, -16(BX) + JMP copy_1_end + +copy_1_small: + CMPQ R11, $0x03 + JE copy_1_move_3 + JB copy_1_move_1or2 + CMPQ R11, $0x08 + JB copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVB (SI), R14 + MOVB -1(SI)(R11*1), R15 + MOVB R14, (BX) + MOVB R15, -1(BX)(R11*1) + ADDQ R11, SI + ADDQ R11, BX + JMP copy_1_end + +copy_1_move_3: + MOVW (SI), R14 + MOVB 2(SI), R15 + MOVW R14, (BX) + MOVB R15, 2(BX) + ADDQ R11, SI + ADDQ R11, BX + JMP copy_1_end + +copy_1_move_4through7: + MOVL (SI), R14 + MOVL -4(SI)(R11*1), R15 + MOVL R14, (BX) + MOVL R15, -4(BX)(R11*1) + ADDQ R11, SI + ADDQ R11, BX + JMP copy_1_end + +copy_1_move_8through16: + MOVQ (SI), R14 + MOVQ -8(SI)(R11*1), R15 + MOVQ R14, (BX) + MOVQ R15, -8(BX)(R11*1) + ADDQ R11, SI + ADDQ R11, BX + +copy_1_end: + ADDQ R11, DI + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + LEAQ (DI)(R10*1), R11 + CMPQ R12, R11 + JG error_match_off_too_big + CMPQ R12, R8 + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, R11 + SUBQ DI, R11 + JLS copy_match + MOVQ R9, R14 + SUBQ R11, R14 + CMPQ R13, R11 + JG copy_all_from_history + MOVQ R13, R11 + SUBQ $0x10, R11 + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R11 + JAE copy_4_loop + LEAQ 16(R14)(R11*1), R14 + LEAQ 16(BX)(R11*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), R11 + MOVB 2(R14), R12 + MOVW R11, (BX) + MOVB R12, 2(BX) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), R11 + MOVL -4(R14)(R13*1), R12 + MOVL R11, (BX) + MOVL R12, -4(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), R11 + MOVQ -8(R14)(R13*1), R12 + MOVQ R11, (BX) + MOVQ R12, -8(BX)(R13*1) + ADDQ R13, R14 + ADDQ R13, BX + +copy_4_end: + ADDQ R13, DI + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + JMP loop_finished + +copy_all_from_history: + MOVQ R11, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R14 + ADDQ $0x10, BX + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(BX)(R15*1), BX + MOVUPS -16(R14), X0 + MOVUPS X0, -16(BX) + JMP copy_5_end + +copy_5_small: + CMPQ R11, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ R11, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(R11*1), BP + MOVB R15, (BX) + MOVB BP, -1(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (BX) + MOVB BP, 2(BX) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(R11*1), BP + MOVL R15, (BX) + MOVL BP, -4(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(R11*1), BP + MOVQ R15, (BX) + MOVQ BP, -8(BX)(R11*1) + ADDQ R11, R14 + ADDQ R11, BX + +copy_5_end: + ADDQ R11, DI + SUBQ R11, R13 + + // Copy match from the current buffer +copy_match: + MOVQ BX, R11 + SUBQ R12, R11 + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, DI + MOVQ R13, R12 + SUBQ $0x10, R12 + JB copy_2_small + +copy_2_loop: + MOVUPS (R11), X0 + MOVUPS X0, (BX) + ADDQ $0x10, R11 + ADDQ $0x10, BX + SUBQ $0x10, R12 + JAE copy_2_loop + LEAQ 16(R11)(R12*1), R11 + LEAQ 16(BX)(R12*1), BX + MOVUPS -16(R11), X0 + MOVUPS X0, -16(BX) + JMP copy_2_end + +copy_2_small: + CMPQ R13, $0x03 + JE copy_2_move_3 + JB copy_2_move_1or2 + CMPQ R13, $0x08 + JB copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVB (R11), R12 + MOVB -1(R11)(R13*1), R14 + MOVB R12, (BX) + MOVB R14, -1(BX)(R13*1) + ADDQ R13, R11 + ADDQ R13, BX + JMP copy_2_end + +copy_2_move_3: + MOVW (R11), R12 + MOVB 2(R11), R14 + MOVW R12, (BX) + MOVB R14, 2(BX) + ADDQ R13, R11 + ADDQ R13, BX + JMP copy_2_end + +copy_2_move_4through7: + MOVL (R11), R12 + MOVL -4(R11)(R13*1), R14 + MOVL R12, (BX) + MOVL R14, -4(BX)(R13*1) + ADDQ R13, R11 + ADDQ R13, BX + JMP copy_2_end + +copy_2_move_8through16: + MOVQ (R11), R12 + MOVQ -8(R11)(R13*1), R14 + MOVQ R12, (BX) + MOVQ R14, -8(BX)(R13*1) + ADDQ R13, R11 + ADDQ R13, BX + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, DI + +copy_slow_3: + MOVB (R11), R12 + MOVB R12, (BX) + INCQ R11 + INCQ BX + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + ADDQ $0x18, AX + INCQ DX + CMPQ DX, CX + JB main_loop + +loop_finished: + // Return value + MOVB $0x01, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + MOVQ 80(AX), CX + SUBQ CX, SI + MOVQ SI, 112(AX) + RET + +error_match_off_too_big: + // Return value + MOVB $0x00, ret+8(FP) + + // Update the context + MOVQ ctx+0(FP), AX + MOVQ DX, 24(AX) + MOVQ DI, 104(AX) + MOVQ 80(AX), CX + SUBQ CX, SI + MOVQ SI, 112(AX) + RET + +empty_seqs: + // Return value + MOVB $0x01, ret+8(FP) + RET + +// func sequenceDecs_decodeSync_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: CMOV, SSE +TEXT ·sequenceDecs_decodeSync_amd64(SB), $64-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + XORQ CX, CX + MOVQ CX, 8(SP) + MOVQ CX, 16(SP) + MOVQ CX, 24(SP) + MOVQ 112(AX), R10 + MOVQ 128(AX), CX + MOVQ CX, 32(SP) + MOVQ 144(AX), R11 + MOVQ 136(AX), R12 + MOVQ 200(AX), CX + MOVQ CX, 56(SP) + MOVQ 176(AX), CX + MOVQ CX, 48(SP) + MOVQ 184(AX), AX + MOVQ AX, 40(SP) + MOVQ 40(SP), AX + ADDQ AX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R10, 32(SP) + + // outBase += outPosition + ADDQ R12, R10 + +sequenceDecs_decodeSync_amd64_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_amd64_fill_end + +sequenceDecs_decodeSync_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_amd64_fill_byte_by_byte + +sequenceDecs_decodeSync_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_of_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_amd64_of_update_zero: + MOVQ AX, 8(SP) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_amd64_ml_update_zero: + MOVQ AX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_amd64_fill_2_end + +sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_amd64_fill_2_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_amd64_fill_2_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte + +sequenceDecs_decodeSync_amd64_fill_2_end: + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_amd64_ll_update_zero: + MOVQ AX, 24(SP) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R13 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R13 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R13 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decodeSync_amd64_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ AX, $0x01 + JBE sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_amd64_after_adjust + +sequenceDecs_decodeSync_amd64_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_amd64_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_amd64_adjust_offset_nonzero + +sequenceDecs_decodeSync_amd64_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_amd64_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_amd64_after_adjust + +sequenceDecs_decodeSync_amd64_adjust_offset_nonzero: + MOVQ R13, AX + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, AX + CMOVQEQ R15, R14 + ADDQ 144(CX)(AX*8), R14 + JNZ sequenceDecs_decodeSync_amd64_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_amd64_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_amd64_adjust_skip + MOVQ 152(CX), AX + MOVQ AX, 160(CX) + +sequenceDecs_decodeSync_amd64_adjust_skip: + MOVQ 144(CX), AX + MOVQ AX, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_amd64_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), AX + MOVQ 24(SP), CX + LEAQ (AX)(CX*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ CX, 104(R14) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decodeSync_amd64_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_amd64_match_len_ofs_ok: + MOVQ 24(SP), AX + MOVQ 8(SP), CX + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (AX)(R13*1), R14 + ADDQ R10, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ AX, AX + JZ check_offset + XORQ R14, R14 + +copy_1: + MOVUPS (R11)(R14*1), X0 + MOVUPS X0, (R10)(R14*1) + ADDQ $0x10, R14 + CMPQ R14, AX + JB copy_1 + ADDQ AX, R11 + ADDQ AX, R10 + ADDQ AX, R12 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R12, AX + ADDQ 40(SP), AX + CMPQ CX, AX + JG error_match_off_too_big + CMPQ CX, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ CX, AX + SUBQ R12, AX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ AX, R14 + CMPQ R13, AX + JG copy_all_from_history + MOVQ R13, AX + SUBQ $0x10, AX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, AX + JAE copy_4_loop + LEAQ 16(R14)(AX*1), R14 + LEAQ 16(R10)(AX*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), AX + MOVB 2(R14), CL + MOVW AX, (R10) + MOVB CL, 2(R10) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), AX + MOVL -4(R14)(R13*1), CX + MOVL AX, (R10) + MOVL CX, -4(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), AX + MOVQ -8(R14)(R13*1), CX + MOVQ AX, (R10) + MOVQ CX, -8(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + +copy_4_end: + ADDQ R13, R12 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ AX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R10)(R15*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_5_end + +copy_5_small: + CMPQ AX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ AX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(AX*1), BP + MOVB R15, (R10) + MOVB BP, -1(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R10) + MOVB BP, 2(R10) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(AX*1), BP + MOVL R15, (R10) + MOVL BP, -4(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(AX*1), BP + MOVQ R15, (R10) + MOVQ BP, -8(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + +copy_5_end: + ADDQ AX, R12 + SUBQ AX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R10, AX + SUBQ CX, AX + + // ml <= mo + CMPQ R13, CX + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R12 + MOVQ R10, CX + ADDQ R13, R10 + +copy_2: + MOVUPS (AX), X0 + MOVUPS X0, (CX) + ADDQ $0x10, AX + ADDQ $0x10, CX + SUBQ $0x10, R13 + JHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R12 + +copy_slow_3: + MOVB (AX), CL + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decodeSync_amd64_main_loop + +loop_finished: + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R12, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R11 + MOVQ R11, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_amd64_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_amd64_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decodeSync_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: BMI, BMI2, CMOV, SSE +TEXT ·sequenceDecs_decodeSync_bmi2(SB), $64-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + XORQ R9, R9 + MOVQ R9, 8(SP) + MOVQ R9, 16(SP) + MOVQ R9, 24(SP) + MOVQ 112(CX), R9 + MOVQ 128(CX), R10 + MOVQ R10, 32(SP) + MOVQ 144(CX), R10 + MOVQ 136(CX), R11 + MOVQ 200(CX), R12 + MOVQ R12, 56(SP) + MOVQ 176(CX), R12 + MOVQ R12, 48(SP) + MOVQ 184(CX), CX + MOVQ CX, 40(SP) + MOVQ 40(SP), CX + ADDQ CX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R9, 32(SP) + + // outBase += outPosition + ADDQ R11, R9 + +sequenceDecs_decodeSync_bmi2_main_loop: + MOVQ (SP), R12 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_bmi2_fill_end + +sequenceDecs_decodeSync_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_bmi2_fill_byte_by_byte + +sequenceDecs_decodeSync_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 8(SP) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_bmi2_fill_2_end + +sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_bmi2_fill_2_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_bmi2_fill_2_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte + +sequenceDecs_decodeSync_bmi2_fill_2_end: + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 24(SP) + + // Fill bitreader for state updates + MOVQ R12, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R12 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_bmi2_skip_update + LEAQ (SI)(DI*1), R13 + ADDQ R8, R13 + MOVBQZX R13, R13 + LEAQ (DX)(R13*1), CX + MOVQ AX, R14 + MOVQ CX, DX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + + // Update Offset State + BZHIQ R8, R14, CX + SHRXQ R8, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R14, CX + SHRXQ DI, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R14, CX + MOVQ $0x00001010, R13 + BEXTRQ R13, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decodeSync_bmi2_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ R12, $0x01 + JBE sequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_bmi2_after_adjust + +sequenceDecs_decodeSync_bmi2_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_bmi2_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero + +sequenceDecs_decodeSync_bmi2_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_bmi2_after_adjust + +sequenceDecs_decodeSync_bmi2_adjust_offset_nonzero: + MOVQ R13, R12 + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, R12 + CMOVQEQ R15, R14 + ADDQ 144(CX)(R12*8), R14 + JNZ sequenceDecs_decodeSync_bmi2_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_bmi2_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_bmi2_adjust_skip + MOVQ 152(CX), R12 + MOVQ R12, 160(CX) + +sequenceDecs_decodeSync_bmi2_adjust_skip: + MOVQ 144(CX), R12 + MOVQ R12, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_bmi2_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), CX + MOVQ 24(SP), R12 + LEAQ (CX)(R12*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ R12, 104(R14) + JS error_not_enough_literals + CMPQ CX, $0x00020002 + JA sequenceDecs_decodeSync_bmi2_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok + TESTQ CX, CX + JNZ sequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_bmi2_match_len_ofs_ok: + MOVQ 24(SP), CX + MOVQ 8(SP), R12 + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (CX)(R13*1), R14 + ADDQ R9, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ CX, CX + JZ check_offset + XORQ R14, R14 + +copy_1: + MOVUPS (R10)(R14*1), X0 + MOVUPS X0, (R9)(R14*1) + ADDQ $0x10, R14 + CMPQ R14, CX + JB copy_1 + ADDQ CX, R10 + ADDQ CX, R9 + ADDQ CX, R11 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R11, CX + ADDQ 40(SP), CX + CMPQ R12, CX + JG error_match_off_too_big + CMPQ R12, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, CX + SUBQ R11, CX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ CX, R14 + CMPQ R13, CX + JG copy_all_from_history + MOVQ R13, CX + SUBQ $0x10, CX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, CX + JAE copy_4_loop + LEAQ 16(R14)(CX*1), R14 + LEAQ 16(R9)(CX*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), CX + MOVB 2(R14), R12 + MOVW CX, (R9) + MOVB R12, 2(R9) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), CX + MOVL -4(R14)(R13*1), R12 + MOVL CX, (R9) + MOVL R12, -4(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), CX + MOVQ -8(R14)(R13*1), R12 + MOVQ CX, (R9) + MOVQ R12, -8(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + +copy_4_end: + ADDQ R13, R11 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ CX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R9)(R15*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_5_end + +copy_5_small: + CMPQ CX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ CX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(CX*1), BP + MOVB R15, (R9) + MOVB BP, -1(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R9) + MOVB BP, 2(R9) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(CX*1), BP + MOVL R15, (R9) + MOVL BP, -4(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(CX*1), BP + MOVQ R15, (R9) + MOVQ BP, -8(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + +copy_5_end: + ADDQ CX, R11 + SUBQ CX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R9, CX + SUBQ R12, CX + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R11 + MOVQ R9, R12 + ADDQ R13, R9 + +copy_2: + MOVUPS (CX), X0 + MOVUPS X0, (R12) + ADDQ $0x10, CX + ADDQ $0x10, R12 + SUBQ $0x10, R13 + JHI copy_2 + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R11 + +copy_slow_3: + MOVB (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decodeSync_bmi2_main_loop + +loop_finished: + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R11, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R10 + MOVQ R10, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_bmi2_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_bmi2_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decodeSync_safe_amd64(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: CMOV, SSE +TEXT ·sequenceDecs_decodeSync_safe_amd64(SB), $64-32 + MOVQ br+8(FP), AX + MOVQ 32(AX), DX + MOVBQZX 40(AX), BX + MOVQ 24(AX), SI + MOVQ (AX), AX + ADDQ SI, AX + MOVQ AX, (SP) + MOVQ ctx+16(FP), AX + MOVQ 72(AX), DI + MOVQ 80(AX), R8 + MOVQ 88(AX), R9 + XORQ CX, CX + MOVQ CX, 8(SP) + MOVQ CX, 16(SP) + MOVQ CX, 24(SP) + MOVQ 112(AX), R10 + MOVQ 128(AX), CX + MOVQ CX, 32(SP) + MOVQ 144(AX), R11 + MOVQ 136(AX), R12 + MOVQ 200(AX), CX + MOVQ CX, 56(SP) + MOVQ 176(AX), CX + MOVQ CX, 48(SP) + MOVQ 184(AX), AX + MOVQ AX, 40(SP) + MOVQ 40(SP), AX + ADDQ AX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R10, 32(SP) + + // outBase += outPosition + ADDQ R12, R10 + +sequenceDecs_decodeSync_safe_amd64_main_loop: + MOVQ (SP), R13 + + // Fill bitreader to have enough for the offset and match length. + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_safe_amd64_fill_end + +sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_safe_amd64_fill_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_safe_amd64_fill_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte + +sequenceDecs_decodeSync_safe_amd64_fill_end: + // Update offset + MOVQ R9, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_of_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_of_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_of_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_safe_amd64_of_update_zero: + MOVQ AX, 8(SP) + + // Update match length + MOVQ R8, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_ml_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_ml_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_ml_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_safe_amd64_ml_update_zero: + MOVQ AX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ SI, $0x08 + JL sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte + MOVQ BX, AX + SHRQ $0x03, AX + SUBQ AX, R13 + MOVQ (R13), DX + SUBQ AX, SI + ANDQ $0x07, BX + JMP sequenceDecs_decodeSync_safe_amd64_fill_2_end + +sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte: + CMPQ SI, $0x00 + JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end + CMPQ BX, $0x07 + JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end + SHLQ $0x08, DX + SUBQ $0x01, R13 + SUBQ $0x01, SI + SUBQ $0x08, BX + MOVBQZX (R13), AX + ORQ AX, DX + JMP sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte + +sequenceDecs_decodeSync_safe_amd64_fill_2_end: + // Update literal length + MOVQ DI, AX + MOVQ BX, CX + MOVQ DX, R14 + SHLQ CL, R14 + MOVB AH, CL + SHRQ $0x20, AX + TESTQ CX, CX + JZ sequenceDecs_decodeSync_safe_amd64_ll_update_zero + ADDQ CX, BX + CMPQ BX, $0x40 + JA sequenceDecs_decodeSync_safe_amd64_ll_update_zero + CMPQ CX, $0x40 + JAE sequenceDecs_decodeSync_safe_amd64_ll_update_zero + NEGQ CX + SHRQ CL, R14 + ADDQ R14, AX + +sequenceDecs_decodeSync_safe_amd64_ll_update_zero: + MOVQ AX, 24(SP) + + // Fill bitreader for state updates + MOVQ R13, (SP) + MOVQ R9, AX + SHRQ $0x08, AX + MOVBQZX AL, AX + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_safe_amd64_skip_update + + // Update Literal Length State + MOVBQZX DI, R13 + SHRQ $0x10, DI + MOVWQZX DI, DI + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, DI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(DI*8), DI + + // Update Match Length State + MOVBQZX R8, R13 + SHRQ $0x10, R8 + MOVWQZX R8, R8 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R8 + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Offset State + MOVBQZX R9, R13 + SHRQ $0x10, R9 + MOVWQZX R9, R9 + LEAQ (BX)(R13*1), CX + MOVQ DX, R14 + MOVQ CX, BX + ROLQ CL, R14 + MOVL $0x00000001, R15 + MOVB R13, CL + SHLL CL, R15 + DECL R15 + ANDQ R15, R14 + ADDQ R14, R9 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R9*8), R9 + +sequenceDecs_decodeSync_safe_amd64_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ AX, $0x01 + JBE sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_safe_amd64_after_adjust + +sequenceDecs_decodeSync_safe_amd64_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero + +sequenceDecs_decodeSync_safe_amd64_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_safe_amd64_after_adjust + +sequenceDecs_decodeSync_safe_amd64_adjust_offset_nonzero: + MOVQ R13, AX + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, AX + CMOVQEQ R15, R14 + ADDQ 144(CX)(AX*8), R14 + JNZ sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_safe_amd64_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_safe_amd64_adjust_skip + MOVQ 152(CX), AX + MOVQ AX, 160(CX) + +sequenceDecs_decodeSync_safe_amd64_adjust_skip: + MOVQ 144(CX), AX + MOVQ AX, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_safe_amd64_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), AX + MOVQ 24(SP), CX + LEAQ (AX)(CX*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ CX, 104(R14) + JS error_not_enough_literals + CMPQ AX, $0x00020002 + JA sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok + TESTQ AX, AX + JNZ sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_safe_amd64_match_len_ofs_ok: + MOVQ 24(SP), AX + MOVQ 8(SP), CX + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (AX)(R13*1), R14 + ADDQ R10, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ AX, AX + JZ check_offset + MOVQ AX, R14 + SUBQ $0x10, R14 + JB copy_1_small + +copy_1_loop: + MOVUPS (R11), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R11 + ADDQ $0x10, R10 + SUBQ $0x10, R14 + JAE copy_1_loop + LEAQ 16(R11)(R14*1), R11 + LEAQ 16(R10)(R14*1), R10 + MOVUPS -16(R11), X0 + MOVUPS X0, -16(R10) + JMP copy_1_end + +copy_1_small: + CMPQ AX, $0x03 + JE copy_1_move_3 + JB copy_1_move_1or2 + CMPQ AX, $0x08 + JB copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVB (R11), R14 + MOVB -1(R11)(AX*1), R15 + MOVB R14, (R10) + MOVB R15, -1(R10)(AX*1) + ADDQ AX, R11 + ADDQ AX, R10 + JMP copy_1_end + +copy_1_move_3: + MOVW (R11), R14 + MOVB 2(R11), R15 + MOVW R14, (R10) + MOVB R15, 2(R10) + ADDQ AX, R11 + ADDQ AX, R10 + JMP copy_1_end + +copy_1_move_4through7: + MOVL (R11), R14 + MOVL -4(R11)(AX*1), R15 + MOVL R14, (R10) + MOVL R15, -4(R10)(AX*1) + ADDQ AX, R11 + ADDQ AX, R10 + JMP copy_1_end + +copy_1_move_8through16: + MOVQ (R11), R14 + MOVQ -8(R11)(AX*1), R15 + MOVQ R14, (R10) + MOVQ R15, -8(R10)(AX*1) + ADDQ AX, R11 + ADDQ AX, R10 + +copy_1_end: + ADDQ AX, R12 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R12, AX + ADDQ 40(SP), AX + CMPQ CX, AX + JG error_match_off_too_big + CMPQ CX, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ CX, AX + SUBQ R12, AX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ AX, R14 + CMPQ R13, AX + JG copy_all_from_history + MOVQ R13, AX + SUBQ $0x10, AX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, AX + JAE copy_4_loop + LEAQ 16(R14)(AX*1), R14 + LEAQ 16(R10)(AX*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), AX + MOVB 2(R14), CL + MOVW AX, (R10) + MOVB CL, 2(R10) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), AX + MOVL -4(R14)(R13*1), CX + MOVL AX, (R10) + MOVL CX, -4(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), AX + MOVQ -8(R14)(R13*1), CX + MOVQ AX, (R10) + MOVQ CX, -8(R10)(R13*1) + ADDQ R13, R14 + ADDQ R13, R10 + +copy_4_end: + ADDQ R13, R12 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ AX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R10) + ADDQ $0x10, R14 + ADDQ $0x10, R10 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R10)(R15*1), R10 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R10) + JMP copy_5_end + +copy_5_small: + CMPQ AX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ AX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(AX*1), BP + MOVB R15, (R10) + MOVB BP, -1(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R10) + MOVB BP, 2(R10) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(AX*1), BP + MOVL R15, (R10) + MOVL BP, -4(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(AX*1), BP + MOVQ R15, (R10) + MOVQ BP, -8(R10)(AX*1) + ADDQ AX, R14 + ADDQ AX, R10 + +copy_5_end: + ADDQ AX, R12 + SUBQ AX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R10, AX + SUBQ CX, AX + + // ml <= mo + CMPQ R13, CX + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R12 + MOVQ R13, CX + SUBQ $0x10, CX + JB copy_2_small + +copy_2_loop: + MOVUPS (AX), X0 + MOVUPS X0, (R10) + ADDQ $0x10, AX + ADDQ $0x10, R10 + SUBQ $0x10, CX + JAE copy_2_loop + LEAQ 16(AX)(CX*1), AX + LEAQ 16(R10)(CX*1), R10 + MOVUPS -16(AX), X0 + MOVUPS X0, -16(R10) + JMP copy_2_end + +copy_2_small: + CMPQ R13, $0x03 + JE copy_2_move_3 + JB copy_2_move_1or2 + CMPQ R13, $0x08 + JB copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVB (AX), CL + MOVB -1(AX)(R13*1), R14 + MOVB CL, (R10) + MOVB R14, -1(R10)(R13*1) + ADDQ R13, AX + ADDQ R13, R10 + JMP copy_2_end + +copy_2_move_3: + MOVW (AX), CX + MOVB 2(AX), R14 + MOVW CX, (R10) + MOVB R14, 2(R10) + ADDQ R13, AX + ADDQ R13, R10 + JMP copy_2_end + +copy_2_move_4through7: + MOVL (AX), CX + MOVL -4(AX)(R13*1), R14 + MOVL CX, (R10) + MOVL R14, -4(R10)(R13*1) + ADDQ R13, AX + ADDQ R13, R10 + JMP copy_2_end + +copy_2_move_8through16: + MOVQ (AX), CX + MOVQ -8(AX)(R13*1), R14 + MOVQ CX, (R10) + MOVQ R14, -8(R10)(R13*1) + ADDQ R13, AX + ADDQ R13, R10 + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R12 + +copy_slow_3: + MOVB (AX), CL + MOVB CL, (R10) + INCQ AX + INCQ R10 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), AX + DECQ 96(AX) + JNS sequenceDecs_decodeSync_safe_amd64_main_loop + +loop_finished: + MOVQ br+8(FP), AX + MOVQ DX, 32(AX) + MOVB BL, 40(AX) + MOVQ SI, 24(AX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R12, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R11 + MOVQ R11, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_safe_amd64_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_safe_amd64_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R12, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET + +// func sequenceDecs_decodeSync_safe_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeSyncAsmContext) int +// Requires: BMI, BMI2, CMOV, SSE +TEXT ·sequenceDecs_decodeSync_safe_bmi2(SB), $64-32 + MOVQ br+8(FP), CX + MOVQ 32(CX), AX + MOVBQZX 40(CX), DX + MOVQ 24(CX), BX + MOVQ (CX), CX + ADDQ BX, CX + MOVQ CX, (SP) + MOVQ ctx+16(FP), CX + MOVQ 72(CX), SI + MOVQ 80(CX), DI + MOVQ 88(CX), R8 + XORQ R9, R9 + MOVQ R9, 8(SP) + MOVQ R9, 16(SP) + MOVQ R9, 24(SP) + MOVQ 112(CX), R9 + MOVQ 128(CX), R10 + MOVQ R10, 32(SP) + MOVQ 144(CX), R10 + MOVQ 136(CX), R11 + MOVQ 200(CX), R12 + MOVQ R12, 56(SP) + MOVQ 176(CX), R12 + MOVQ R12, 48(SP) + MOVQ 184(CX), CX + MOVQ CX, 40(SP) + MOVQ 40(SP), CX + ADDQ CX, 48(SP) + + // Calculate poiter to s.out[cap(s.out)] (a past-end pointer) + ADDQ R9, 32(SP) + + // outBase += outPosition + ADDQ R11, R9 + +sequenceDecs_decodeSync_safe_bmi2_main_loop: + MOVQ (SP), R12 + + // Fill bitreader to have enough for the offset and match length. + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_end + +sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte + +sequenceDecs_decodeSync_safe_bmi2_fill_end: + // Update offset + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ R8, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 8(SP) + + // Update match length + MOVQ $0x00000808, CX + BEXTRQ CX, DI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ DI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 16(SP) + + // Fill bitreader to have enough for the remaining + CMPQ BX, $0x08 + JL sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte + MOVQ DX, CX + SHRQ $0x03, CX + SUBQ CX, R12 + MOVQ (R12), AX + SUBQ CX, BX + ANDQ $0x07, DX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_end + +sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte: + CMPQ BX, $0x00 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end + CMPQ DX, $0x07 + JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end + SHLQ $0x08, AX + SUBQ $0x01, R12 + SUBQ $0x01, BX + SUBQ $0x08, DX + MOVBQZX (R12), CX + ORQ CX, AX + JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte + +sequenceDecs_decodeSync_safe_bmi2_fill_2_end: + // Update literal length + MOVQ $0x00000808, CX + BEXTRQ CX, SI, R13 + MOVQ AX, R14 + LEAQ (DX)(R13*1), CX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + MOVQ CX, DX + MOVQ SI, CX + SHRQ $0x20, CX + ADDQ R14, CX + MOVQ CX, 24(SP) + + // Fill bitreader for state updates + MOVQ R12, (SP) + MOVQ $0x00000808, CX + BEXTRQ CX, R8, R12 + MOVQ ctx+16(FP), CX + CMPQ 96(CX), $0x00 + JZ sequenceDecs_decodeSync_safe_bmi2_skip_update + LEAQ (SI)(DI*1), R13 + ADDQ R8, R13 + MOVBQZX R13, R13 + LEAQ (DX)(R13*1), CX + MOVQ AX, R14 + MOVQ CX, DX + ROLQ CL, R14 + BZHIQ R13, R14, R14 + + // Update Offset State + BZHIQ R8, R14, CX + SHRXQ R8, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, R8, R8 + ADDQ CX, R8 + + // Load ctx.ofTable + MOVQ ctx+16(FP), CX + MOVQ 48(CX), CX + MOVQ (CX)(R8*8), R8 + + // Update Match Length State + BZHIQ DI, R14, CX + SHRXQ DI, R14, R14 + MOVQ $0x00001010, R13 + BEXTRQ R13, DI, DI + ADDQ CX, DI + + // Load ctx.mlTable + MOVQ ctx+16(FP), CX + MOVQ 24(CX), CX + MOVQ (CX)(DI*8), DI + + // Update Literal Length State + BZHIQ SI, R14, CX + MOVQ $0x00001010, R13 + BEXTRQ R13, SI, SI + ADDQ CX, SI + + // Load ctx.llTable + MOVQ ctx+16(FP), CX + MOVQ (CX), CX + MOVQ (CX)(SI*8), SI + +sequenceDecs_decodeSync_safe_bmi2_skip_update: + // Adjust offset + MOVQ s+0(FP), CX + MOVQ 8(SP), R13 + CMPQ R12, $0x01 + JBE sequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0 + MOVUPS 144(CX), X0 + MOVQ R13, 144(CX) + MOVUPS X0, 152(CX) + JMP sequenceDecs_decodeSync_safe_bmi2_after_adjust + +sequenceDecs_decodeSync_safe_bmi2_adjust_offsetB_1_or_0: + CMPQ 24(SP), $0x00000000 + JNE sequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero + INCQ R13 + JMP sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero + +sequenceDecs_decodeSync_safe_bmi2_adjust_offset_maybezero: + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero + MOVQ 144(CX), R13 + JMP sequenceDecs_decodeSync_safe_bmi2_after_adjust + +sequenceDecs_decodeSync_safe_bmi2_adjust_offset_nonzero: + MOVQ R13, R12 + XORQ R14, R14 + MOVQ $-1, R15 + CMPQ R13, $0x03 + CMOVQEQ R14, R12 + CMOVQEQ R15, R14 + ADDQ 144(CX)(R12*8), R14 + JNZ sequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid + MOVQ $0x00000001, R14 + +sequenceDecs_decodeSync_safe_bmi2_adjust_temp_valid: + CMPQ R13, $0x01 + JZ sequenceDecs_decodeSync_safe_bmi2_adjust_skip + MOVQ 152(CX), R12 + MOVQ R12, 160(CX) + +sequenceDecs_decodeSync_safe_bmi2_adjust_skip: + MOVQ 144(CX), R12 + MOVQ R12, 152(CX) + MOVQ R14, 144(CX) + MOVQ R14, R13 + +sequenceDecs_decodeSync_safe_bmi2_after_adjust: + MOVQ R13, 8(SP) + + // Check values + MOVQ 16(SP), CX + MOVQ 24(SP), R12 + LEAQ (CX)(R12*1), R14 + MOVQ s+0(FP), R15 + ADDQ R14, 256(R15) + MOVQ ctx+16(FP), R14 + SUBQ R12, 104(R14) + JS error_not_enough_literals + CMPQ CX, $0x00020002 + JA sequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big + TESTQ R13, R13 + JNZ sequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok + TESTQ CX, CX + JNZ sequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch + +sequenceDecs_decodeSync_safe_bmi2_match_len_ofs_ok: + MOVQ 24(SP), CX + MOVQ 8(SP), R12 + MOVQ 16(SP), R13 + + // Check if we have enough space in s.out + LEAQ (CX)(R13*1), R14 + ADDQ R9, R14 + CMPQ R14, 32(SP) + JA error_not_enough_space + + // Copy literals + TESTQ CX, CX + JZ check_offset + MOVQ CX, R14 + SUBQ $0x10, R14 + JB copy_1_small + +copy_1_loop: + MOVUPS (R10), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R10 + ADDQ $0x10, R9 + SUBQ $0x10, R14 + JAE copy_1_loop + LEAQ 16(R10)(R14*1), R10 + LEAQ 16(R9)(R14*1), R9 + MOVUPS -16(R10), X0 + MOVUPS X0, -16(R9) + JMP copy_1_end + +copy_1_small: + CMPQ CX, $0x03 + JE copy_1_move_3 + JB copy_1_move_1or2 + CMPQ CX, $0x08 + JB copy_1_move_4through7 + JMP copy_1_move_8through16 + +copy_1_move_1or2: + MOVB (R10), R14 + MOVB -1(R10)(CX*1), R15 + MOVB R14, (R9) + MOVB R15, -1(R9)(CX*1) + ADDQ CX, R10 + ADDQ CX, R9 + JMP copy_1_end + +copy_1_move_3: + MOVW (R10), R14 + MOVB 2(R10), R15 + MOVW R14, (R9) + MOVB R15, 2(R9) + ADDQ CX, R10 + ADDQ CX, R9 + JMP copy_1_end + +copy_1_move_4through7: + MOVL (R10), R14 + MOVL -4(R10)(CX*1), R15 + MOVL R14, (R9) + MOVL R15, -4(R9)(CX*1) + ADDQ CX, R10 + ADDQ CX, R9 + JMP copy_1_end + +copy_1_move_8through16: + MOVQ (R10), R14 + MOVQ -8(R10)(CX*1), R15 + MOVQ R14, (R9) + MOVQ R15, -8(R9)(CX*1) + ADDQ CX, R10 + ADDQ CX, R9 + +copy_1_end: + ADDQ CX, R11 + + // Malformed input if seq.mo > t+len(hist) || seq.mo > s.windowSize) +check_offset: + MOVQ R11, CX + ADDQ 40(SP), CX + CMPQ R12, CX + JG error_match_off_too_big + CMPQ R12, 56(SP) + JG error_match_off_too_big + + // Copy match from history + MOVQ R12, CX + SUBQ R11, CX + JLS copy_match + MOVQ 48(SP), R14 + SUBQ CX, R14 + CMPQ R13, CX + JG copy_all_from_history + MOVQ R13, CX + SUBQ $0x10, CX + JB copy_4_small + +copy_4_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, CX + JAE copy_4_loop + LEAQ 16(R14)(CX*1), R14 + LEAQ 16(R9)(CX*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_4_end + +copy_4_small: + CMPQ R13, $0x03 + JE copy_4_move_3 + CMPQ R13, $0x08 + JB copy_4_move_4through7 + JMP copy_4_move_8through16 + +copy_4_move_3: + MOVW (R14), CX + MOVB 2(R14), R12 + MOVW CX, (R9) + MOVB R12, 2(R9) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_4through7: + MOVL (R14), CX + MOVL -4(R14)(R13*1), R12 + MOVL CX, (R9) + MOVL R12, -4(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + JMP copy_4_end + +copy_4_move_8through16: + MOVQ (R14), CX + MOVQ -8(R14)(R13*1), R12 + MOVQ CX, (R9) + MOVQ R12, -8(R9)(R13*1) + ADDQ R13, R14 + ADDQ R13, R9 + +copy_4_end: + ADDQ R13, R11 + JMP handle_loop + JMP loop_finished + +copy_all_from_history: + MOVQ CX, R15 + SUBQ $0x10, R15 + JB copy_5_small + +copy_5_loop: + MOVUPS (R14), X0 + MOVUPS X0, (R9) + ADDQ $0x10, R14 + ADDQ $0x10, R9 + SUBQ $0x10, R15 + JAE copy_5_loop + LEAQ 16(R14)(R15*1), R14 + LEAQ 16(R9)(R15*1), R9 + MOVUPS -16(R14), X0 + MOVUPS X0, -16(R9) + JMP copy_5_end + +copy_5_small: + CMPQ CX, $0x03 + JE copy_5_move_3 + JB copy_5_move_1or2 + CMPQ CX, $0x08 + JB copy_5_move_4through7 + JMP copy_5_move_8through16 + +copy_5_move_1or2: + MOVB (R14), R15 + MOVB -1(R14)(CX*1), BP + MOVB R15, (R9) + MOVB BP, -1(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_3: + MOVW (R14), R15 + MOVB 2(R14), BP + MOVW R15, (R9) + MOVB BP, 2(R9) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_4through7: + MOVL (R14), R15 + MOVL -4(R14)(CX*1), BP + MOVL R15, (R9) + MOVL BP, -4(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + JMP copy_5_end + +copy_5_move_8through16: + MOVQ (R14), R15 + MOVQ -8(R14)(CX*1), BP + MOVQ R15, (R9) + MOVQ BP, -8(R9)(CX*1) + ADDQ CX, R14 + ADDQ CX, R9 + +copy_5_end: + ADDQ CX, R11 + SUBQ CX, R13 + + // Copy match from the current buffer +copy_match: + MOVQ R9, CX + SUBQ R12, CX + + // ml <= mo + CMPQ R13, R12 + JA copy_overlapping_match + + // Copy non-overlapping match + ADDQ R13, R11 + MOVQ R13, R12 + SUBQ $0x10, R12 + JB copy_2_small + +copy_2_loop: + MOVUPS (CX), X0 + MOVUPS X0, (R9) + ADDQ $0x10, CX + ADDQ $0x10, R9 + SUBQ $0x10, R12 + JAE copy_2_loop + LEAQ 16(CX)(R12*1), CX + LEAQ 16(R9)(R12*1), R9 + MOVUPS -16(CX), X0 + MOVUPS X0, -16(R9) + JMP copy_2_end + +copy_2_small: + CMPQ R13, $0x03 + JE copy_2_move_3 + JB copy_2_move_1or2 + CMPQ R13, $0x08 + JB copy_2_move_4through7 + JMP copy_2_move_8through16 + +copy_2_move_1or2: + MOVB (CX), R12 + MOVB -1(CX)(R13*1), R14 + MOVB R12, (R9) + MOVB R14, -1(R9)(R13*1) + ADDQ R13, CX + ADDQ R13, R9 + JMP copy_2_end + +copy_2_move_3: + MOVW (CX), R12 + MOVB 2(CX), R14 + MOVW R12, (R9) + MOVB R14, 2(R9) + ADDQ R13, CX + ADDQ R13, R9 + JMP copy_2_end + +copy_2_move_4through7: + MOVL (CX), R12 + MOVL -4(CX)(R13*1), R14 + MOVL R12, (R9) + MOVL R14, -4(R9)(R13*1) + ADDQ R13, CX + ADDQ R13, R9 + JMP copy_2_end + +copy_2_move_8through16: + MOVQ (CX), R12 + MOVQ -8(CX)(R13*1), R14 + MOVQ R12, (R9) + MOVQ R14, -8(R9)(R13*1) + ADDQ R13, CX + ADDQ R13, R9 + +copy_2_end: + JMP handle_loop + + // Copy overlapping match +copy_overlapping_match: + ADDQ R13, R11 + +copy_slow_3: + MOVB (CX), R12 + MOVB R12, (R9) + INCQ CX + INCQ R9 + DECQ R13 + JNZ copy_slow_3 + +handle_loop: + MOVQ ctx+16(FP), CX + DECQ 96(CX) + JNS sequenceDecs_decodeSync_safe_bmi2_main_loop + +loop_finished: + MOVQ br+8(FP), CX + MOVQ AX, 32(CX) + MOVB DL, 40(CX) + MOVQ BX, 24(CX) + + // Update the context + MOVQ ctx+16(FP), AX + MOVQ R11, 136(AX) + MOVQ 144(AX), CX + SUBQ CX, R10 + MOVQ R10, 168(AX) + + // Return success + MOVQ $0x00000000, ret+24(FP) + RET + + // Return with match length error +sequenceDecs_decodeSync_safe_bmi2_error_match_len_ofs_mismatch: + MOVQ 16(SP), AX + MOVQ ctx+16(FP), CX + MOVQ AX, 216(CX) + MOVQ $0x00000001, ret+24(FP) + RET + + // Return with match too long error +sequenceDecs_decodeSync_safe_bmi2_error_match_len_too_big: + MOVQ ctx+16(FP), AX + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ $0x00000002, ret+24(FP) + RET + + // Return with match offset too long error +error_match_off_too_big: + MOVQ ctx+16(FP), AX + MOVQ 8(SP), CX + MOVQ CX, 224(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000003, ret+24(FP) + RET + + // Return with not enough literals error +error_not_enough_literals: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ $0x00000004, ret+24(FP) + RET + + // Return with not enough output space error +error_not_enough_space: + MOVQ ctx+16(FP), AX + MOVQ 24(SP), CX + MOVQ CX, 208(AX) + MOVQ 16(SP), CX + MOVQ CX, 216(AX) + MOVQ R11, 136(AX) + MOVQ $0x00000005, ret+24(FP) + RET diff --git a/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go new file mode 100644 index 000000000..c3452bc3a --- /dev/null +++ b/vendor/github.com/klauspost/compress/zstd/seqdec_generic.go @@ -0,0 +1,237 @@ +//go:build !amd64 || appengine || !gc || noasm +// +build !amd64 appengine !gc noasm + +package zstd + +import ( + "fmt" + "io" +) + +// decode sequences from the stream with the provided history but without dictionary. +func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) { + return false, nil +} + +// decode sequences from the stream without the provided history. +func (s *sequenceDecs) decode(seqs []seqVals) error { + br := s.br + + // Grab full sizes tables, to avoid bounds checks. + llTable, mlTable, ofTable := s.litLengths.fse.dt[:maxTablesize], s.matchLengths.fse.dt[:maxTablesize], s.offsets.fse.dt[:maxTablesize] + llState, mlState, ofState := s.litLengths.state.state, s.matchLengths.state.state, s.offsets.state.state + s.seqSize = 0 + litRemain := len(s.literals) + + maxBlockSize := maxCompressedBlockSize + if s.windowSize < maxBlockSize { + maxBlockSize = s.windowSize + } + for i := range seqs { + var ll, mo, ml int + if br.off > 4+((maxOffsetBits+16+16)>>3) { + // inlined function: + // ll, mo, ml = s.nextFast(br, llState, mlState, ofState) + + // Final will not read from stream. + var llB, mlB, moB uint8 + ll, llB = llState.final() + ml, mlB = mlState.final() + mo, moB = ofState.final() + + // extra bits are stored in reverse order. + br.fillFast() + mo += br.getBits(moB) + if s.maxBits > 32 { + br.fillFast() + } + ml += br.getBits(mlB) + ll += br.getBits(llB) + + if moB > 1 { + s.prevOffset[2] = s.prevOffset[1] + s.prevOffset[1] = s.prevOffset[0] + s.prevOffset[0] = mo + } else { + // mo = s.adjustOffset(mo, ll, moB) + // Inlined for rather big speedup + if ll == 0 { + // There is an exception though, when current sequence's literals_length = 0. + // In this case, repeated offsets are shifted by one, so an offset_value of 1 means Repeated_Offset2, + // an offset_value of 2 means Repeated_Offset3, and an offset_value of 3 means Repeated_Offset1 - 1_byte. + mo++ + } + + if mo == 0 { + mo = s.prevOffset[0] + } else { + var temp int + if mo == 3 { + temp = s.prevOffset[0] - 1 + } else { + temp = s.prevOffset[mo] + } + + if temp == 0 { + // 0 is not valid; input is corrupted; force offset to 1 + println("WARNING: temp was 0") + temp = 1 + } + + if mo != 1 { + s.prevOffset[2] = s.prevOffset[1] + } + s.prevOffset[1] = s.prevOffset[0] + s.prevOffset[0] = temp + mo = temp + } + } + br.fillFast() + } else { + if br.overread() { + if debugDecoder { + printf("reading sequence %d, exceeded available data\n", i) + } + return io.ErrUnexpectedEOF + } + ll, mo, ml = s.next(br, llState, mlState, ofState) + br.fill() + } + + if debugSequences { + println("Seq", i, "Litlen:", ll, "mo:", mo, "(abs) ml:", ml) + } + // Evaluate. + // We might be doing this async, so do it early. + if mo == 0 && ml > 0 { + return fmt.Errorf("zero matchoff and matchlen (%d) > 0", ml) + } + if ml > maxMatchLen { + return fmt.Errorf("match len (%d) bigger than max allowed length", ml) + } + s.seqSize += ll + ml + if s.seqSize > maxBlockSize { + return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + } + litRemain -= ll + if litRemain < 0 { + return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, litRemain+ll) + } + seqs[i] = seqVals{ + ll: ll, + ml: ml, + mo: mo, + } + if i == len(seqs)-1 { + // This is the last sequence, so we shouldn't update state. + break + } + + // Manually inlined, ~ 5-20% faster + // Update all 3 states at once. Approx 20% faster. + nBits := llState.nbBits() + mlState.nbBits() + ofState.nbBits() + if nBits == 0 { + llState = llTable[llState.newState()&maxTableMask] + mlState = mlTable[mlState.newState()&maxTableMask] + ofState = ofTable[ofState.newState()&maxTableMask] + } else { + bits := br.get32BitsFast(nBits) + lowBits := uint16(bits >> ((ofState.nbBits() + mlState.nbBits()) & 31)) + llState = llTable[(llState.newState()+lowBits)&maxTableMask] + + lowBits = uint16(bits >> (ofState.nbBits() & 31)) + lowBits &= bitMask[mlState.nbBits()&15] + mlState = mlTable[(mlState.newState()+lowBits)&maxTableMask] + + lowBits = uint16(bits) & bitMask[ofState.nbBits()&15] + ofState = ofTable[(ofState.newState()+lowBits)&maxTableMask] + } + } + s.seqSize += litRemain + if s.seqSize > maxBlockSize { + return fmt.Errorf("output (%d) bigger than max block size (%d)", s.seqSize, maxBlockSize) + } + err := br.close() + if err != nil { + printf("Closing sequences: %v, %+v\n", err, *br) + } + return err +} + +// executeSimple handles cases when a dictionary is not used. +func (s *sequenceDecs) executeSimple(seqs []seqVals, hist []byte) error { + // Ensure we have enough output size... + if len(s.out)+s.seqSize > cap(s.out) { + addBytes := s.seqSize + len(s.out) + s.out = append(s.out, make([]byte, addBytes)...) + s.out = s.out[:len(s.out)-addBytes] + } + + if debugDecoder { + printf("Execute %d seqs with literals: %d into %d bytes\n", len(seqs), len(s.literals), s.seqSize) + } + + var t = len(s.out) + out := s.out[:t+s.seqSize] + + for _, seq := range seqs { + // Add literals + copy(out[t:], s.literals[:seq.ll]) + t += seq.ll + s.literals = s.literals[seq.ll:] + + // Malformed input + if seq.mo > t+len(hist) || seq.mo > s.windowSize { + return fmt.Errorf("match offset (%d) bigger than current history (%d)", seq.mo, t+len(hist)) + } + + // Copy from history. + if v := seq.mo - t; v > 0 { + // v is the start position in history from end. + start := len(hist) - v + if seq.ml > v { + // Some goes into the current block. + // Copy remainder of history + copy(out[t:], hist[start:]) + t += v + seq.ml -= v + } else { + copy(out[t:], hist[start:start+seq.ml]) + t += seq.ml + continue + } + } + + // We must be in the current buffer now + if seq.ml > 0 { + start := t - seq.mo + if seq.ml <= t-start { + // No overlap + copy(out[t:], out[start:start+seq.ml]) + t += seq.ml + } else { + // Overlapping copy + // Extend destination slice and copy one byte at the time. + src := out[start : start+seq.ml] + dst := out[t:] + dst = dst[:len(src)] + t += len(src) + // Destination is the space we just added. + for i := range src { + dst[i] = src[i] + } + } + } + } + // Add final literals + copy(out[t:], s.literals) + if debugDecoder { + t += len(s.literals) + if t != len(out) { + panic(fmt.Errorf("length mismatch, want %d, got %d, ss: %d", len(out), t, s.seqSize)) + } + } + s.out = out + + return nil +} diff --git a/vendor/github.com/klauspost/compress/zstd/zip.go b/vendor/github.com/klauspost/compress/zstd/zip.go index ffffcbc25..29c15c8c4 100644 --- a/vendor/github.com/klauspost/compress/zstd/zip.go +++ b/vendor/github.com/klauspost/compress/zstd/zip.go @@ -18,26 +18,44 @@ const ZipMethodWinZip = 93 // See https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.9.TXT const ZipMethodPKWare = 20 -var zipReaderPool sync.Pool +// zipReaderPool is the default reader pool. +var zipReaderPool = sync.Pool{New: func() interface{} { + z, err := NewReader(nil, WithDecoderLowmem(true), WithDecoderMaxWindow(128<<20), WithDecoderConcurrency(1)) + if err != nil { + panic(err) + } + return z +}} // newZipReader creates a pooled zip decompressor. -func newZipReader(r io.Reader) io.ReadCloser { - dec, ok := zipReaderPool.Get().(*Decoder) - if ok { - dec.Reset(r) - } else { - d, err := NewReader(r, WithDecoderConcurrency(1), WithDecoderLowmem(true)) - if err != nil { - panic(err) - } - dec = d +func newZipReader(opts ...DOption) func(r io.Reader) io.ReadCloser { + pool := &zipReaderPool + if len(opts) > 0 { + opts = append([]DOption{WithDecoderLowmem(true), WithDecoderMaxWindow(128 << 20)}, opts...) + // Force concurrency 1 + opts = append(opts, WithDecoderConcurrency(1)) + // Create our own pool + pool = &sync.Pool{} + } + return func(r io.Reader) io.ReadCloser { + dec, ok := pool.Get().(*Decoder) + if ok { + dec.Reset(r) + } else { + d, err := NewReader(r, opts...) + if err != nil { + panic(err) + } + dec = d + } + return &pooledZipReader{dec: dec, pool: pool} } - return &pooledZipReader{dec: dec} } type pooledZipReader struct { - mu sync.Mutex // guards Close and Read - dec *Decoder + mu sync.Mutex // guards Close and Read + pool *sync.Pool + dec *Decoder } func (r *pooledZipReader) Read(p []byte) (n int, err error) { @@ -48,8 +66,8 @@ func (r *pooledZipReader) Read(p []byte) (n int, err error) { } dec, err := r.dec.Read(p) if err == io.EOF { - err = r.dec.Reset(nil) - zipReaderPool.Put(r.dec) + r.dec.Reset(nil) + r.pool.Put(r.dec) r.dec = nil } return dec, err @@ -61,7 +79,7 @@ func (r *pooledZipReader) Close() error { var err error if r.dec != nil { err = r.dec.Reset(nil) - zipReaderPool.Put(r.dec) + r.pool.Put(r.dec) r.dec = nil } return err @@ -115,6 +133,9 @@ func ZipCompressor(opts ...EOption) func(w io.Writer) (io.WriteCloser, error) { // ZipDecompressor returns a decompressor that can be registered with zip libraries. // See ZipCompressor for example. -func ZipDecompressor() func(r io.Reader) io.ReadCloser { - return newZipReader +// Options can be specified. WithDecoderConcurrency(1) is forced, +// and by default a 128MB maximum decompression window is specified. +// The window size can be overridden if required. +func ZipDecompressor(opts ...DOption) func(r io.Reader) io.ReadCloser { + return newZipReader(opts...) } diff --git a/vendor/github.com/klauspost/compress/zstd/zstd.go b/vendor/github.com/klauspost/compress/zstd/zstd.go index c1c90b4a0..3eb3f1c82 100644 --- a/vendor/github.com/klauspost/compress/zstd/zstd.go +++ b/vendor/github.com/klauspost/compress/zstd/zstd.go @@ -110,17 +110,6 @@ func printf(format string, a ...interface{}) { } } -// matchLenFast does matching, but will not match the last up to 7 bytes. -func matchLenFast(a, b []byte) int { - endI := len(a) & (math.MaxInt32 - 7) - for i := 0; i < endI; i += 8 { - if diff := load64(a, i) ^ load64(b, i); diff != 0 { - return i + bits.TrailingZeros64(diff)>>3 - } - } - return endI -} - // matchLen returns the maximum length. // a must be the shortest of the two. // The function also returns whether all bytes matched. diff --git a/vendor/github.com/klauspost/cpuid/v2/cpuid.go b/vendor/github.com/klauspost/cpuid/v2/cpuid.go index bec4c2494..27f33250e 100644 --- a/vendor/github.com/klauspost/cpuid/v2/cpuid.go +++ b/vendor/github.com/klauspost/cpuid/v2/cpuid.go @@ -93,7 +93,8 @@ const ( AVX512VNNI // AVX-512 Vector Neural Network Instructions AVX512VP2INTERSECT // AVX-512 Intersect for D/Q AVX512VPOPCNTDQ // AVX-512 Vector Population Count Doubleword and Quadword - AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one. + AVXSLOW // Indicates the CPU performs 2 128 bit operations instead of one + AVXVNNI // AVX (VEX encoded) VNNI neural network instructions BMI1 // Bit Manipulation Instruction Set 1 BMI2 // Bit Manipulation Instruction Set 2 CETIBT // Intel CET Indirect Branch Tracking @@ -102,6 +103,7 @@ const ( CLMUL // Carry-less Multiplication CLZERO // CLZERO instruction supported CMOV // i686 CMOV + CMPSB_SCADBS_SHORT // Fast short CMPSB and SCASB CMPXCHG8 // CMPXCHG8 instruction CPBOOST // Core Performance Boost CX16 // CMPXCHG16B Instruction @@ -112,8 +114,9 @@ const ( FMA4 // Bulldozer FMA4 functions FXSR // FXSAVE, FXRESTOR instructions, CR4 bit 9 FXSROPT // FXSAVE/FXRSTOR optimizations - GFNI // Galois Field New Instructions + GFNI // Galois Field New Instructions. May require other features (AVX, AVX512VL,AVX512F) based on usage. HLE // Hardware Lock Elision + HRESET // If set CPU supports history reset and the IA32_HRESET_ENABLE MSR HTT // Hyperthreading (enabled) HWA // Hardware assert supported. Indicates support for MSRC001_10 HYPERVISOR // This bit has been reserved by Intel & AMD for use by hypervisors @@ -131,6 +134,8 @@ const ( INT_WBINVD // WBINVD/WBNOINVD are interruptible. INVLPGB // NVLPGB and TLBSYNC instruction supported LAHF // LAHF/SAHF in long mode + LAM // If set, CPU supports Linear Address Masking + LBRVIRT // LBR virtualization LZCNT // LZCNT instruction MCAOVERFLOW // MCA overflow recovery support. MCOMMIT // MCOMMIT instruction supported @@ -139,9 +144,11 @@ const ( MOVBE // MOVBE instruction (big-endian) MOVDIR64B // Move 64 Bytes as Direct Store MOVDIRI // Move Doubleword as Direct Store + MOVSB_ZL // Fast Zero-Length MOVSB MPX // Intel MPX (Memory Protection Extensions) - MSR_PAGEFLUSH // Page Flush MSR available MSRIRC // Instruction Retired Counter MSR available + MSR_PAGEFLUSH // Page Flush MSR available + NRIPS // Indicates support for NRIP save on VMEXIT NX // NX (No-Execute) bit OSXSAVE // XSAVE enabled by OS PCONFIG // PCONFIG for Intel Multi-Key Total Memory Encryption @@ -152,7 +159,6 @@ const ( RDTSCP // RDTSCP Instruction RTM // Restricted Transactional Memory RTM_ALWAYS_ABORT // Indicates that the loaded microcode is forcing RTM abort. - SCE // SYSENTER and SYSEXIT instructions SERIALIZE // Serialize Instruction Execution SEV // AMD Secure Encrypted Virtualization supported SEV_64BIT // AMD SEV guest execution only allowed from a 64-bit host @@ -174,15 +180,28 @@ const ( SSE4A // AMD Barcelona microarchitecture SSE4a instructions SSSE3 // Conroe SSSE3 functions STIBP // Single Thread Indirect Branch Predictors + STOSB_SHORT // Fast short STOSB SUCCOR // Software uncorrectable error containment and recovery capability. + SVM // AMD Secure Virtual Machine + SVMDA // Indicates support for the SVM decode assists. + SVMFBASID // SVM, Indicates that TLB flush events, including CR3 writes and CR4.PGE toggles, flush only the current ASID's TLB entries. Also indicates support for the extended VMCBTLB_Control + SVML // AMD SVM lock. Indicates support for SVM-Lock. + SVMNP // AMD SVM nested paging + SVMPF // SVM pause intercept filter. Indicates support for the pause intercept filter + SVMPFT // SVM PAUSE filter threshold. Indicates support for the PAUSE filter cycle count threshold + SYSCALL // System-Call Extension (SCE): SYSCALL and SYSRET instructions. + SYSEE // SYSENTER and SYSEXIT instructions TBM // AMD Trailing Bit Manipulation + TOPEXT // TopologyExtensions: topology extensions support. Indicates support for CPUID Fn8000_001D_EAX_x[N:0]-CPUID Fn8000_001E_EDX. TME // Intel Total Memory Encryption. The following MSRs are supported: IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK, and IA32_TME_EXCLUDE_BASE. + TSCRATEMSR // MSR based TSC rate control. Indicates support for MSR TSC ratio MSRC000_0104 TSXLDTRK // Intel TSX Suspend Load Address Tracking - VAES // Vector AES + VAES // Vector AES. AVX(512) versions requires additional checks. + VMCBCLEAN // VMCB clean bits. Indicates support for VMCB clean bits. VMPL // AMD VM Permission Levels supported VMSA_REGPROT // AMD VMSA Register Protection supported VMX // Virtual Machine Extensions - VPCLMULQDQ // Carry-Less Multiplication Quadword + VPCLMULQDQ // Carry-Less Multiplication Quadword. Requires AVX for 3 register versions. VTE // AMD Virtual Transparent Encryption supported WAITPKG // TPAUSE, UMONITOR, UMWAIT WBNOINVD // Write Back and Do Not Invalidate Cache @@ -219,7 +238,6 @@ const ( SM3 // SM3 instructions SM4 // SM4 instructions SVE // Scalable Vector Extension - // Keep it last. It automatically defines the size of []flagSet lastID @@ -237,6 +255,7 @@ type CPUInfo struct { LogicalCores int // Number of physical cores times threads that can run on each core through the use of hyperthreading. Will be 0 if undetectable. Family int // CPU family number Model int // CPU model number + Stepping int // CPU stepping info CacheLine int // Cache line size in bytes. Will be 0 if undetectable. Hz int64 // Clock speed, if known, 0 otherwise. Will attempt to contain base clock speed. BoostFreq int64 // Max clock speed, if known, 0 otherwise @@ -343,11 +362,21 @@ func (c CPUInfo) Has(id FeatureID) bool { return c.featureSet.inSet(id) } +// AnyOf returns whether the CPU supports one or more of the requested features. +func (c CPUInfo) AnyOf(ids ...FeatureID) bool { + for _, id := range ids { + if c.featureSet.inSet(id) { + return true + } + } + return false +} + // https://en.wikipedia.org/wiki/X86-64#Microarchitecture_levels -var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2) -var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3) -var level3Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE) -var level4Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SCE, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL) +var level1Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2) +var level2Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3) +var level3Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE) +var level4Features = flagSetWith(CMOV, CMPXCHG8, X87, FXSR, MMX, SYSCALL, SSE, SSE2, CX16, LAHF, POPCNT, SSE3, SSE4, SSE42, SSSE3, AVX, AVX2, BMI1, BMI2, F16C, FMA3, LZCNT, MOVBE, OSXSAVE, AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL) // X64Level returns the microarchitecture level detected on the CPU. // If features are lacking or non x64 mode, 0 is returned. @@ -661,7 +690,7 @@ func threadsPerCore() int { if vend == AMD { // Workaround for AMD returning 0, assume 2 if >= Zen 2 // It will be more correct than not. - fam, _ := familyModel() + fam, _, _ := familyModel() _, _, _, d := cpuid(1) if (d&(1<<28)) != 0 && fam >= 23 { return 2 @@ -699,14 +728,27 @@ func logicalCores() int { } } -func familyModel() (int, int) { +func familyModel() (family, model, stepping int) { if maxFunctionID() < 0x1 { - return 0, 0 + return 0, 0, 0 } eax, _, _, _ := cpuid(1) - family := ((eax >> 8) & 0xf) + ((eax >> 20) & 0xff) - model := ((eax >> 4) & 0xf) + ((eax >> 12) & 0xf0) - return int(family), int(model) + // If BaseFamily[3:0] is less than Fh then ExtendedFamily[7:0] is reserved and Family is equal to BaseFamily[3:0]. + family = int((eax >> 8) & 0xf) + extFam := family == 0x6 // Intel is 0x6, needs extended model. + if family == 0xf { + // Add ExtFamily + family += int((eax >> 20) & 0xff) + extFam = true + } + // If BaseFamily[3:0] is less than 0Fh then ExtendedModel[3:0] is reserved and Model is equal to BaseModel[3:0]. + model = int((eax >> 4) & 0xf) + if extFam { + // Add ExtModel + model += int((eax >> 12) & 0xf0) + } + stepping = int(eax & 0xf) + return family, model, stepping } func physicalCores() int { @@ -841,7 +883,7 @@ func (c *CPUInfo) cacheSize() { c.Cache.L2 = int(((ecx >> 16) & 0xFFFF) * 1024) // CPUID Fn8000_001D_EAX_x[N:0] Cache Properties - if maxExtendedFunction() < 0x8000001D { + if maxExtendedFunction() < 0x8000001D || !c.Has(TOPEXT) { return } @@ -958,14 +1000,13 @@ func support() flagSet { if mfi < 0x1 { return fs } - family, model := familyModel() + family, model, _ := familyModel() _, _, c, d := cpuid(1) fs.setIf((d&(1<<0)) != 0, X87) fs.setIf((d&(1<<8)) != 0, CMPXCHG8) - fs.setIf((d&(1<<11)) != 0, SCE) + fs.setIf((d&(1<<11)) != 0, SYSEE) fs.setIf((d&(1<<15)) != 0, CMOV) - fs.setIf((d&(1<<22)) != 0, MMXEXT) fs.setIf((d&(1<<23)) != 0, MMX) fs.setIf((d&(1<<24)) != 0, FXSR) fs.setIf((d&(1<<25)) != 0, FXSROPT) @@ -973,9 +1014,9 @@ func support() flagSet { fs.setIf((d&(1<<26)) != 0, SSE2) fs.setIf((c&1) != 0, SSE3) fs.setIf((c&(1<<5)) != 0, VMX) - fs.setIf((c&0x00000200) != 0, SSSE3) - fs.setIf((c&0x00080000) != 0, SSE4) - fs.setIf((c&0x00100000) != 0, SSE42) + fs.setIf((c&(1<<9)) != 0, SSSE3) + fs.setIf((c&(1<<19)) != 0, SSE4) + fs.setIf((c&(1<<20)) != 0, SSE42) fs.setIf((c&(1<<25)) != 0, AESNI) fs.setIf((c&(1<<1)) != 0, CLMUL) fs.setIf(c&(1<<22) != 0, MOVBE) @@ -1021,7 +1062,6 @@ func support() flagSet { // Check AVX2, AVX2 requires OS support, but BMI1/2 don't. if mfi >= 7 { _, ebx, ecx, edx := cpuidex(7, 0) - eax1, _, _, _ := cpuidex(7, 1) if fs.inSet(AVX) && (ebx&0x00000020) != 0 { fs.set(AVX2) } @@ -1038,15 +1078,20 @@ func support() flagSet { fs.setIf(ebx&(1<<18) != 0, RDSEED) fs.setIf(ebx&(1<<19) != 0, ADX) fs.setIf(ebx&(1<<29) != 0, SHA) + // CPUID.(EAX=7, ECX=0).ECX fs.setIf(ecx&(1<<5) != 0, WAITPKG) fs.setIf(ecx&(1<<7) != 0, CETSS) + fs.setIf(ecx&(1<<8) != 0, GFNI) + fs.setIf(ecx&(1<<9) != 0, VAES) + fs.setIf(ecx&(1<<10) != 0, VPCLMULQDQ) fs.setIf(ecx&(1<<13) != 0, TME) fs.setIf(ecx&(1<<25) != 0, CLDEMOTE) fs.setIf(ecx&(1<<27) != 0, MOVDIRI) fs.setIf(ecx&(1<<28) != 0, MOVDIR64B) fs.setIf(ecx&(1<<29) != 0, ENQCMD) fs.setIf(ecx&(1<<30) != 0, SGXLC) + // CPUID.(EAX=7, ECX=0).EDX fs.setIf(edx&(1<<11) != 0, RTM_ALWAYS_ABORT) fs.setIf(edx&(1<<14) != 0, SERIALIZE) @@ -1056,6 +1101,15 @@ func support() flagSet { fs.setIf(edx&(1<<26) != 0, IBPB) fs.setIf(edx&(1<<27) != 0, STIBP) + // CPUID.(EAX=7, ECX=1) + eax1, _, _, _ := cpuidex(7, 1) + fs.setIf(fs.inSet(AVX) && eax1&(1<<4) != 0, AVXVNNI) + fs.setIf(eax1&(1<<10) != 0, MOVSB_ZL) + fs.setIf(eax1&(1<<11) != 0, STOSB_SHORT) + fs.setIf(eax1&(1<<12) != 0, CMPSB_SCADBS_SHORT) + fs.setIf(eax1&(1<<22) != 0, HRESET) + fs.setIf(eax1&(1<<26) != 0, LAM) + // Only detect AVX-512 features if XGETBV is supported if c&((1<<26)|(1<<27)) == (1<<26)|(1<<27) { // Check for OS support @@ -1080,9 +1134,6 @@ func support() flagSet { // ecx fs.setIf(ecx&(1<<1) != 0, AVX512VBMI) fs.setIf(ecx&(1<<6) != 0, AVX512VBMI2) - fs.setIf(ecx&(1<<8) != 0, GFNI) - fs.setIf(ecx&(1<<9) != 0, VAES) - fs.setIf(ecx&(1<<10) != 0, VPCLMULQDQ) fs.setIf(ecx&(1<<11) != 0, AVX512VNNI) fs.setIf(ecx&(1<<12) != 0, AVX512BITALG) fs.setIf(ecx&(1<<14) != 0, AVX512VPOPCNTDQ) @@ -1125,21 +1176,29 @@ func support() flagSet { fs.set(LZCNT) fs.set(POPCNT) } + // ECX fs.setIf((c&(1<<0)) != 0, LAHF) - fs.setIf((c&(1<<10)) != 0, IBS) - fs.setIf((d&(1<<31)) != 0, AMD3DNOW) - fs.setIf((d&(1<<30)) != 0, AMD3DNOWEXT) - fs.setIf((d&(1<<23)) != 0, MMX) - fs.setIf((d&(1<<22)) != 0, MMXEXT) + fs.setIf((c&(1<<2)) != 0, SVM) fs.setIf((c&(1<<6)) != 0, SSE4A) + fs.setIf((c&(1<<10)) != 0, IBS) + fs.setIf((c&(1<<22)) != 0, TOPEXT) + + // EDX + fs.setIf(d&(1<<11) != 0, SYSCALL) fs.setIf(d&(1<<20) != 0, NX) + fs.setIf(d&(1<<22) != 0, MMXEXT) + fs.setIf(d&(1<<23) != 0, MMX) + fs.setIf(d&(1<<24) != 0, FXSR) + fs.setIf(d&(1<<25) != 0, FXSROPT) fs.setIf(d&(1<<27) != 0, RDTSCP) + fs.setIf(d&(1<<30) != 0, AMD3DNOWEXT) + fs.setIf(d&(1<<31) != 0, AMD3DNOW) /* XOP and FMA4 use the AVX instruction coding scheme, so they can't be * used unless the OS has AVX support. */ if fs.inSet(AVX) { - fs.setIf((c&0x00000800) != 0, XOP) - fs.setIf((c&0x00010000) != 0, FMA4) + fs.setIf((c&(1<<11)) != 0, XOP) + fs.setIf((c&(1<<16)) != 0, FMA4) } } @@ -1162,6 +1221,20 @@ func support() flagSet { fs.setIf((b&(1<<0)) != 0, CLZERO) } + if fs.inSet(SVM) && maxExtendedFunction() >= 0x8000000A { + _, _, _, edx := cpuid(0x8000000A) + fs.setIf((edx>>0)&1 == 1, SVMNP) + fs.setIf((edx>>1)&1 == 1, LBRVIRT) + fs.setIf((edx>>2)&1 == 1, SVML) + fs.setIf((edx>>3)&1 == 1, NRIPS) + fs.setIf((edx>>4)&1 == 1, TSCRATEMSR) + fs.setIf((edx>>5)&1 == 1, VMCBCLEAN) + fs.setIf((edx>>6)&1 == 1, SVMFBASID) + fs.setIf((edx>>7)&1 == 1, SVMDA) + fs.setIf((edx>>10)&1 == 1, SVMPF) + fs.setIf((edx>>12)&1 == 1, SVMPFT) + } + if maxExtendedFunction() >= 0x8000001b && fs.inSet(IBS) { eax, _, _, _ := cpuid(0x8000001b) fs.setIf((eax>>0)&1 == 1, IBSFFV) diff --git a/vendor/github.com/klauspost/cpuid/v2/detect_x86.go b/vendor/github.com/klauspost/cpuid/v2/detect_x86.go index 35678d8a3..c946824ec 100644 --- a/vendor/github.com/klauspost/cpuid/v2/detect_x86.go +++ b/vendor/github.com/klauspost/cpuid/v2/detect_x86.go @@ -24,7 +24,7 @@ func addInfo(c *CPUInfo, safe bool) { c.maxExFunc = maxExtendedFunction() c.BrandName = brandName() c.CacheLine = cacheLine() - c.Family, c.Model = familyModel() + c.Family, c.Model, c.Stepping = familyModel() c.featureSet = support() c.SGX = hasSGX(c.featureSet.inSet(SGX), c.featureSet.inSet(SGXLC)) c.ThreadsPerCore = threadsPerCore() diff --git a/vendor/github.com/klauspost/cpuid/v2/featureid_string.go b/vendor/github.com/klauspost/cpuid/v2/featureid_string.go index 8cf57cae8..d12e547c4 100644 --- a/vendor/github.com/klauspost/cpuid/v2/featureid_string.go +++ b/vendor/github.com/klauspost/cpuid/v2/featureid_string.go @@ -34,136 +34,155 @@ func _() { _ = x[AVX512VP2INTERSECT-24] _ = x[AVX512VPOPCNTDQ-25] _ = x[AVXSLOW-26] - _ = x[BMI1-27] - _ = x[BMI2-28] - _ = x[CETIBT-29] - _ = x[CETSS-30] - _ = x[CLDEMOTE-31] - _ = x[CLMUL-32] - _ = x[CLZERO-33] - _ = x[CMOV-34] - _ = x[CMPXCHG8-35] - _ = x[CPBOOST-36] - _ = x[CX16-37] - _ = x[ENQCMD-38] - _ = x[ERMS-39] - _ = x[F16C-40] - _ = x[FMA3-41] - _ = x[FMA4-42] - _ = x[FXSR-43] - _ = x[FXSROPT-44] - _ = x[GFNI-45] - _ = x[HLE-46] - _ = x[HTT-47] - _ = x[HWA-48] - _ = x[HYPERVISOR-49] - _ = x[IBPB-50] - _ = x[IBS-51] - _ = x[IBSBRNTRGT-52] - _ = x[IBSFETCHSAM-53] - _ = x[IBSFFV-54] - _ = x[IBSOPCNT-55] - _ = x[IBSOPCNTEXT-56] - _ = x[IBSOPSAM-57] - _ = x[IBSRDWROPCNT-58] - _ = x[IBSRIPINVALIDCHK-59] - _ = x[IBS_PREVENTHOST-60] - _ = x[INT_WBINVD-61] - _ = x[INVLPGB-62] - _ = x[LAHF-63] - _ = x[LZCNT-64] - _ = x[MCAOVERFLOW-65] - _ = x[MCOMMIT-66] - _ = x[MMX-67] - _ = x[MMXEXT-68] - _ = x[MOVBE-69] - _ = x[MOVDIR64B-70] - _ = x[MOVDIRI-71] - _ = x[MPX-72] - _ = x[MSR_PAGEFLUSH-73] - _ = x[MSRIRC-74] - _ = x[NX-75] - _ = x[OSXSAVE-76] - _ = x[PCONFIG-77] - _ = x[POPCNT-78] - _ = x[RDPRU-79] - _ = x[RDRAND-80] - _ = x[RDSEED-81] - _ = x[RDTSCP-82] - _ = x[RTM-83] - _ = x[RTM_ALWAYS_ABORT-84] - _ = x[SCE-85] - _ = x[SERIALIZE-86] - _ = x[SEV-87] - _ = x[SEV_64BIT-88] - _ = x[SEV_ALTERNATIVE-89] - _ = x[SEV_DEBUGSWAP-90] - _ = x[SEV_ES-91] - _ = x[SEV_RESTRICTED-92] - _ = x[SEV_SNP-93] - _ = x[SGX-94] - _ = x[SGXLC-95] - _ = x[SHA-96] - _ = x[SME-97] - _ = x[SME_COHERENT-98] - _ = x[SSE-99] - _ = x[SSE2-100] - _ = x[SSE3-101] - _ = x[SSE4-102] - _ = x[SSE42-103] - _ = x[SSE4A-104] - _ = x[SSSE3-105] - _ = x[STIBP-106] - _ = x[SUCCOR-107] - _ = x[TBM-108] - _ = x[TME-109] - _ = x[TSXLDTRK-110] - _ = x[VAES-111] - _ = x[VMPL-112] - _ = x[VMSA_REGPROT-113] - _ = x[VMX-114] - _ = x[VPCLMULQDQ-115] - _ = x[VTE-116] - _ = x[WAITPKG-117] - _ = x[WBNOINVD-118] - _ = x[X87-119] - _ = x[XGETBV1-120] - _ = x[XOP-121] - _ = x[XSAVE-122] - _ = x[XSAVEC-123] - _ = x[XSAVEOPT-124] - _ = x[XSAVES-125] - _ = x[AESARM-126] - _ = x[ARMCPUID-127] - _ = x[ASIMD-128] - _ = x[ASIMDDP-129] - _ = x[ASIMDHP-130] - _ = x[ASIMDRDM-131] - _ = x[ATOMICS-132] - _ = x[CRC32-133] - _ = x[DCPOP-134] - _ = x[EVTSTRM-135] - _ = x[FCMA-136] - _ = x[FP-137] - _ = x[FPHP-138] - _ = x[GPA-139] - _ = x[JSCVT-140] - _ = x[LRCPC-141] - _ = x[PMULL-142] - _ = x[SHA1-143] - _ = x[SHA2-144] - _ = x[SHA3-145] - _ = x[SHA512-146] - _ = x[SM3-147] - _ = x[SM4-148] - _ = x[SVE-149] - _ = x[lastID-150] + _ = x[AVXVNNI-27] + _ = x[BMI1-28] + _ = x[BMI2-29] + _ = x[CETIBT-30] + _ = x[CETSS-31] + _ = x[CLDEMOTE-32] + _ = x[CLMUL-33] + _ = x[CLZERO-34] + _ = x[CMOV-35] + _ = x[CMPSB_SCADBS_SHORT-36] + _ = x[CMPXCHG8-37] + _ = x[CPBOOST-38] + _ = x[CX16-39] + _ = x[ENQCMD-40] + _ = x[ERMS-41] + _ = x[F16C-42] + _ = x[FMA3-43] + _ = x[FMA4-44] + _ = x[FXSR-45] + _ = x[FXSROPT-46] + _ = x[GFNI-47] + _ = x[HLE-48] + _ = x[HRESET-49] + _ = x[HTT-50] + _ = x[HWA-51] + _ = x[HYPERVISOR-52] + _ = x[IBPB-53] + _ = x[IBS-54] + _ = x[IBSBRNTRGT-55] + _ = x[IBSFETCHSAM-56] + _ = x[IBSFFV-57] + _ = x[IBSOPCNT-58] + _ = x[IBSOPCNTEXT-59] + _ = x[IBSOPSAM-60] + _ = x[IBSRDWROPCNT-61] + _ = x[IBSRIPINVALIDCHK-62] + _ = x[IBS_PREVENTHOST-63] + _ = x[INT_WBINVD-64] + _ = x[INVLPGB-65] + _ = x[LAHF-66] + _ = x[LAM-67] + _ = x[LBRVIRT-68] + _ = x[LZCNT-69] + _ = x[MCAOVERFLOW-70] + _ = x[MCOMMIT-71] + _ = x[MMX-72] + _ = x[MMXEXT-73] + _ = x[MOVBE-74] + _ = x[MOVDIR64B-75] + _ = x[MOVDIRI-76] + _ = x[MOVSB_ZL-77] + _ = x[MPX-78] + _ = x[MSRIRC-79] + _ = x[MSR_PAGEFLUSH-80] + _ = x[NRIPS-81] + _ = x[NX-82] + _ = x[OSXSAVE-83] + _ = x[PCONFIG-84] + _ = x[POPCNT-85] + _ = x[RDPRU-86] + _ = x[RDRAND-87] + _ = x[RDSEED-88] + _ = x[RDTSCP-89] + _ = x[RTM-90] + _ = x[RTM_ALWAYS_ABORT-91] + _ = x[SERIALIZE-92] + _ = x[SEV-93] + _ = x[SEV_64BIT-94] + _ = x[SEV_ALTERNATIVE-95] + _ = x[SEV_DEBUGSWAP-96] + _ = x[SEV_ES-97] + _ = x[SEV_RESTRICTED-98] + _ = x[SEV_SNP-99] + _ = x[SGX-100] + _ = x[SGXLC-101] + _ = x[SHA-102] + _ = x[SME-103] + _ = x[SME_COHERENT-104] + _ = x[SSE-105] + _ = x[SSE2-106] + _ = x[SSE3-107] + _ = x[SSE4-108] + _ = x[SSE42-109] + _ = x[SSE4A-110] + _ = x[SSSE3-111] + _ = x[STIBP-112] + _ = x[STOSB_SHORT-113] + _ = x[SUCCOR-114] + _ = x[SVM-115] + _ = x[SVMDA-116] + _ = x[SVMFBASID-117] + _ = x[SVML-118] + _ = x[SVMNP-119] + _ = x[SVMPF-120] + _ = x[SVMPFT-121] + _ = x[SYSCALL-122] + _ = x[SYSEE-123] + _ = x[TBM-124] + _ = x[TOPEXT-125] + _ = x[TME-126] + _ = x[TSCRATEMSR-127] + _ = x[TSXLDTRK-128] + _ = x[VAES-129] + _ = x[VMCBCLEAN-130] + _ = x[VMPL-131] + _ = x[VMSA_REGPROT-132] + _ = x[VMX-133] + _ = x[VPCLMULQDQ-134] + _ = x[VTE-135] + _ = x[WAITPKG-136] + _ = x[WBNOINVD-137] + _ = x[X87-138] + _ = x[XGETBV1-139] + _ = x[XOP-140] + _ = x[XSAVE-141] + _ = x[XSAVEC-142] + _ = x[XSAVEOPT-143] + _ = x[XSAVES-144] + _ = x[AESARM-145] + _ = x[ARMCPUID-146] + _ = x[ASIMD-147] + _ = x[ASIMDDP-148] + _ = x[ASIMDHP-149] + _ = x[ASIMDRDM-150] + _ = x[ATOMICS-151] + _ = x[CRC32-152] + _ = x[DCPOP-153] + _ = x[EVTSTRM-154] + _ = x[FCMA-155] + _ = x[FP-156] + _ = x[FPHP-157] + _ = x[GPA-158] + _ = x[JSCVT-159] + _ = x[LRCPC-160] + _ = x[PMULL-161] + _ = x[SHA1-162] + _ = x[SHA2-163] + _ = x[SHA3-164] + _ = x[SHA512-165] + _ = x[SM3-166] + _ = x[SM4-167] + _ = x[SVE-168] + _ = x[lastID-169] _ = x[firstID-0] } -const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPXCHG8CPBOOSTCX16ENQCMDERMSF16CFMA3FMA4FXSRFXSROPTGFNIHLEHTTHWAHYPERVISORIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_PREVENTHOSTINT_WBINVDINVLPGBLAHFLZCNTMCAOVERFLOWMCOMMITMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMPXMSR_PAGEFLUSHMSRIRCNXOSXSAVEPCONFIGPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSCESERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSUCCORTBMTMETSXLDTRKVAESVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID" +const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXINT8AMXTILEAVXAVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXSLOWAVXVNNIBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCX16ENQCMDERMSF16CFMA3FMA4FXSRFXSROPTGFNIHLEHRESETHTTHWAHYPERVISORIBPBIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_PREVENTHOSTINT_WBINVDINVLPGBLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCOMMITMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMPXMSRIRCMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTRDPRURDRANDRDSEEDRDTSCPRTMRTM_ALWAYS_ABORTSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTOPEXTTMETSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID" -var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 234, 238, 244, 249, 257, 262, 268, 272, 280, 287, 291, 297, 301, 305, 309, 313, 317, 324, 328, 331, 334, 337, 347, 351, 354, 364, 375, 381, 389, 400, 408, 420, 436, 451, 461, 468, 472, 477, 488, 495, 498, 504, 509, 518, 525, 528, 541, 547, 549, 556, 563, 569, 574, 580, 586, 592, 595, 611, 614, 623, 626, 635, 650, 663, 669, 683, 690, 693, 698, 701, 704, 716, 719, 723, 727, 731, 736, 741, 746, 751, 757, 760, 763, 771, 775, 779, 791, 794, 804, 807, 814, 822, 825, 832, 835, 840, 846, 854, 860, 866, 874, 879, 886, 893, 901, 908, 913, 918, 925, 929, 931, 935, 938, 943, 948, 953, 957, 961, 965, 971, 974, 977, 980, 986} +var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 58, 62, 72, 84, 92, 100, 108, 116, 123, 133, 143, 151, 161, 172, 180, 190, 208, 223, 230, 237, 241, 245, 251, 256, 264, 269, 275, 279, 297, 305, 312, 316, 322, 326, 330, 334, 338, 342, 349, 353, 356, 362, 365, 368, 378, 382, 385, 395, 406, 412, 420, 431, 439, 451, 467, 482, 492, 499, 503, 506, 513, 518, 529, 536, 539, 545, 550, 559, 566, 574, 577, 583, 596, 601, 603, 610, 617, 623, 628, 634, 640, 646, 649, 665, 674, 677, 686, 701, 714, 720, 734, 741, 744, 749, 752, 755, 767, 770, 774, 778, 782, 787, 792, 797, 802, 813, 819, 822, 827, 836, 840, 845, 850, 856, 863, 868, 871, 877, 880, 890, 898, 902, 911, 915, 927, 930, 940, 943, 950, 958, 961, 968, 971, 976, 982, 990, 996, 1002, 1010, 1015, 1022, 1029, 1037, 1044, 1049, 1054, 1061, 1065, 1067, 1071, 1074, 1079, 1084, 1089, 1093, 1097, 1101, 1107, 1110, 1113, 1116, 1122} func (i FeatureID) String() string { if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) { diff --git a/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go b/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go index 8d2cb0368..d91d02109 100644 --- a/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go +++ b/vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go @@ -2,18 +2,120 @@ package cpuid -import "runtime" +import ( + "runtime" + "strings" + + "golang.org/x/sys/unix" +) func detectOS(c *CPUInfo) bool { + if runtime.GOOS != "ios" { + tryToFillCPUInfoFomSysctl(c) + } // There are no hw.optional sysctl values for the below features on Mac OS 11.0 // to detect their supported state dynamically. Assume the CPU features that // Apple Silicon M1 supports to be available as a minimal set of features // to all Go programs running on darwin/arm64. // TODO: Add more if we know them. c.featureSet.setIf(runtime.GOOS != "ios", AESARM, PMULL, SHA1, SHA2) - c.PhysicalCores = runtime.NumCPU() - // For now assuming 1 thread per core... - c.ThreadsPerCore = 1 - c.LogicalCores = c.PhysicalCores + return true } + +func sysctlGetBool(name string) bool { + value, err := unix.SysctlUint32(name) + if err != nil { + return false + } + return value != 0 +} + +func sysctlGetString(name string) string { + value, err := unix.Sysctl(name) + if err != nil { + return "" + } + return value +} + +func sysctlGetInt(unknown int, names ...string) int { + for _, name := range names { + value, err := unix.SysctlUint32(name) + if err != nil { + continue + } + if value != 0 { + return int(value) + } + } + return unknown +} + +func sysctlGetInt64(unknown int, names ...string) int { + for _, name := range names { + value64, err := unix.SysctlUint64(name) + if err != nil { + continue + } + if int(value64) != unknown { + return int(value64) + } + } + return unknown +} + +func setFeature(c *CPUInfo, name string, feature FeatureID) { + c.featureSet.setIf(sysctlGetBool(name), feature) +} +func tryToFillCPUInfoFomSysctl(c *CPUInfo) { + c.BrandName = sysctlGetString("machdep.cpu.brand_string") + + if len(c.BrandName) != 0 { + c.VendorString = strings.Fields(c.BrandName)[0] + } + + c.PhysicalCores = sysctlGetInt(runtime.NumCPU(), "hw.physicalcpu") + c.ThreadsPerCore = sysctlGetInt(1, "machdep.cpu.thread_count", "kern.num_threads") / + sysctlGetInt(1, "hw.physicalcpu") + c.LogicalCores = sysctlGetInt(runtime.NumCPU(), "machdep.cpu.core_count") + c.Family = sysctlGetInt(0, "machdep.cpu.family", "hw.cpufamily") + c.Model = sysctlGetInt(0, "machdep.cpu.model") + c.CacheLine = sysctlGetInt64(0, "hw.cachelinesize") + c.Cache.L1I = sysctlGetInt64(-1, "hw.l1icachesize") + c.Cache.L1D = sysctlGetInt64(-1, "hw.l1icachesize") + c.Cache.L2 = sysctlGetInt64(-1, "hw.l2cachesize") + c.Cache.L3 = sysctlGetInt64(-1, "hw.l3cachesize") + + // from https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile + setFeature(c, "hw.optional.arm.FEAT_AES", AESARM) + setFeature(c, "hw.optional.AdvSIMD", ASIMD) + setFeature(c, "hw.optional.arm.FEAT_DotProd", ASIMDDP) + setFeature(c, "hw.optional.arm.FEAT_RDM", ASIMDRDM) + setFeature(c, "hw.optional.FEAT_CRC32", CRC32) + setFeature(c, "hw.optional.arm.FEAT_DPB", DCPOP) + // setFeature(c, "", EVTSTRM) + setFeature(c, "hw.optional.arm.FEAT_FCMA", FCMA) + setFeature(c, "hw.optional.arm.FEAT_FP", FP) + setFeature(c, "hw.optional.arm.FEAT_FP16", FPHP) + setFeature(c, "hw.optional.arm.FEAT_PAuth", GPA) + setFeature(c, "hw.optional.arm.FEAT_JSCVT", JSCVT) + setFeature(c, "hw.optional.arm.FEAT_LRCPC", LRCPC) + setFeature(c, "hw.optional.arm.FEAT_PMULL", PMULL) + setFeature(c, "hw.optional.arm.FEAT_SHA1", SHA1) + setFeature(c, "hw.optional.arm.FEAT_SHA256", SHA2) + setFeature(c, "hw.optional.arm.FEAT_SHA3", SHA3) + setFeature(c, "hw.optional.arm.FEAT_SHA512", SHA512) + // setFeature(c, "", SM3) + // setFeature(c, "", SM4) + setFeature(c, "hw.optional.arm.FEAT_SVE", SVE) + + // from empirical observation + setFeature(c, "hw.optional.AdvSIMD_HPFPCvt", ASIMDHP) + setFeature(c, "hw.optional.armv8_1_atomics", ATOMICS) + setFeature(c, "hw.optional.floatingpoint", FP) + setFeature(c, "hw.optional.armv8_2_sha3", SHA3) + setFeature(c, "hw.optional.armv8_2_sha512", SHA512) + setFeature(c, "hw.optional.armv8_3_compnum", FCMA) + setFeature(c, "hw.optional.armv8_crc32", CRC32) +} diff --git a/vendor/github.com/libp2p/go-eventbus/.travis.yml b/vendor/github.com/libp2p/go-eventbus/.travis.yml deleted file mode 100644 index a156d3eb5..000000000 --- a/vendor/github.com/libp2p/go-eventbus/.travis.yml +++ /dev/null @@ -1,30 +0,0 @@ -os: - - linux - -language: go - -go: - - 1.13.x - -env: - global: - - GOTFLAGS="-race" - matrix: - - BUILD_DEPTYPE=gomod - - -# disable travis install -install: - - true - -script: - - bash <(curl -s https://raw.githubusercontent.com/ipfs/ci-helpers/master/travis-ci/run-standard-tests.sh) - - -cache: - directories: - - $GOPATH/pkg/mod - - $HOME/.cache/go-build - -notifications: - email: false diff --git a/vendor/github.com/libp2p/go-eventbus/README.md b/vendor/github.com/libp2p/go-eventbus/README.md deleted file mode 100644 index 6cd56ac47..000000000 --- a/vendor/github.com/libp2p/go-eventbus/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# go-eventbus - -[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) -[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) -[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) -[![GoDoc](https://godoc.org/github.com/libp2p/go-eventbus?status.svg)](https://godoc.org/github.com/libp2p/go-eventbus) -[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-eventbus/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-eventbus?branch=master) -[![Build Status](https://travis-ci.com/libp2p/go-eventbus.svg?branch=master)](https://travis-ci.com/libp2p/go-eventbus) -[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) - -> Simple and fast eventbus for type-based local event delivery. - -## Install - -```sh -go get github.com/libp2p/go-eventbus -``` - -## Usage - -Check out the [GoDocs](https://godoc.org/github.com/libp2p/go-eventbus). - -## License - -Dual-licensed under MIT and ASLv2, by way of the [Permissive License Stack](https://protocol.ai/blog/announcing-the-permissive-license-stack/). diff --git a/vendor/github.com/libp2p/go-eventbus/codecov.yml b/vendor/github.com/libp2p/go-eventbus/codecov.yml deleted file mode 100644 index 5f88a9ea2..000000000 --- a/vendor/github.com/libp2p/go-eventbus/codecov.yml +++ /dev/null @@ -1,3 +0,0 @@ -coverage: - range: "50...100" -comment: off diff --git a/vendor/github.com/libp2p/go-flow-metrics/.travis.yml b/vendor/github.com/libp2p/go-flow-metrics/.travis.yml index 5163d693f..67e608fef 100644 --- a/vendor/github.com/libp2p/go-flow-metrics/.travis.yml +++ b/vendor/github.com/libp2p/go-flow-metrics/.travis.yml @@ -4,7 +4,7 @@ os: language: go go: - - 1.11.x + - 1.17.x env: global: diff --git a/vendor/github.com/libp2p/go-flow-metrics/sweeper.go b/vendor/github.com/libp2p/go-flow-metrics/sweeper.go index ceed13fac..8b9a2624d 100644 --- a/vendor/github.com/libp2p/go-flow-metrics/sweeper.go +++ b/vendor/github.com/libp2p/go-flow-metrics/sweeper.go @@ -5,6 +5,8 @@ import ( "sync" "sync/atomic" "time" + + "github.com/benbjohnson/clock" ) // IdleRate the rate at which we declare a meter idle (and stop tracking it @@ -20,6 +22,14 @@ var alpha = 1 - math.Exp(-1.0) // The global sweeper. var globalSweeper sweeper +var cl = clock.New() + +// SetClock sets a clock to use in the sweeper. +// This will probably only ever be useful for testing purposes. +func SetClock(c clock.Clock) { + cl = c +} + type sweeper struct { sweepOnce sync.Once @@ -53,10 +63,10 @@ func (sw *sweeper) register(m *Meter) { } func (sw *sweeper) runActive() { - ticker := time.NewTicker(time.Second) + ticker := cl.Ticker(time.Second) defer ticker.Stop() - sw.lastUpdateTime = time.Now() + sw.lastUpdateTime = cl.Now() for len(sw.meters) > 0 { // Scale back allocation. if len(sw.meters)*2 < cap(sw.meters) { @@ -80,7 +90,7 @@ func (sw *sweeper) update() { sw.snapshotMu.Lock() defer sw.snapshotMu.Unlock() - now := time.Now() + now := cl.Now() tdiff := now.Sub(sw.lastUpdateTime) if tdiff <= 0 { return diff --git a/vendor/github.com/libp2p/go-libp2p-core/LICENSE b/vendor/github.com/libp2p/go-libp2p-core/LICENSE deleted file mode 100644 index 770d1744d..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/LICENSE +++ /dev/null @@ -1,4 +0,0 @@ -Dual-licensed under MIT and ASLv2, by way of the [Permissive License Stack](https://protocol.ai/blog/announcing-the-permissive-license-stack/). - -Apache-2.0: https://www.apache.org/licenses/license-2.0 -MIT: https://www.opensource.org/licenses/mit diff --git a/vendor/github.com/libp2p/go-libp2p-core/LICENSE-APACHE b/vendor/github.com/libp2p/go-libp2p-core/LICENSE-APACHE deleted file mode 100644 index 546514363..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/LICENSE-APACHE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2019. Protocol Labs, Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/vendor/github.com/libp2p/go-libp2p-core/LICENSE-MIT b/vendor/github.com/libp2p/go-libp2p-core/LICENSE-MIT deleted file mode 100644 index ea532a830..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/LICENSE-MIT +++ /dev/null @@ -1,19 +0,0 @@ -Copyright 2019. Protocol Labs, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/doc.go b/vendor/github.com/libp2p/go-libp2p-core/event/doc.go deleted file mode 100644 index 3a070f3af..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/event/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -// Package event contains the abstractions for a local event bus, along with the standard events -// that libp2p subsystems may emit. -// -// Source code is arranged as follows: -// * doc.go: this file. -// * bus.go: abstractions for the event bus. -// * rest: event structs, sensibly categorised in files by entity, and following this naming convention: -// Evt[Entity (noun)][Event (verb past tense / gerund)] -// The past tense is used to convey that something happened, whereas the gerund form of the verb (-ing) -// expresses that a process is in progress. Examples: EvtConnEstablishing, EvtConnEstablished. -package event diff --git a/vendor/github.com/libp2p/go-libp2p-core/test/addrs.go b/vendor/github.com/libp2p/go-libp2p-core/test/addrs.go deleted file mode 100644 index e18849c48..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/test/addrs.go +++ /dev/null @@ -1,42 +0,0 @@ -package test - -import ( - "fmt" - "testing" - - ma "github.com/multiformats/go-multiaddr" -) - -func GenerateTestAddrs(n int) []ma.Multiaddr { - out := make([]ma.Multiaddr, n) - for i := 0; i < n; i++ { - a, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/1.2.3.4/tcp/%d", i)) - if err != nil { - continue - } - out[i] = a - } - return out -} - -func AssertAddressesEqual(t *testing.T, exp, act []ma.Multiaddr) { - t.Helper() - if len(exp) != len(act) { - t.Fatalf("lengths not the same. expected %d, got %d\n", len(exp), len(act)) - } - - for _, a := range exp { - found := false - - for _, b := range act { - if a.Equal(b) { - found = true - break - } - } - - if !found { - t.Fatalf("expected address %s not found", a) - } - } -} diff --git a/vendor/github.com/libp2p/go-libp2p-core/test/crypto.go b/vendor/github.com/libp2p/go-libp2p-core/test/crypto.go deleted file mode 100644 index 8733cf924..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/test/crypto.go +++ /dev/null @@ -1,21 +0,0 @@ -package test - -import ( - "math/rand" - "sync/atomic" - - ci "github.com/libp2p/go-libp2p-core/crypto" -) - -var globalSeed int64 - -func RandTestKeyPair(typ, bits int) (ci.PrivKey, ci.PubKey, error) { - // workaround for low time resolution - seed := atomic.AddInt64(&globalSeed, 1) - return SeededTestKeyPair(typ, bits, seed) -} - -func SeededTestKeyPair(typ, bits int, seed int64) (ci.PrivKey, ci.PubKey, error) { - r := rand.New(rand.NewSource(seed)) - return ci.GenerateKeyPairWithReader(typ, bits, r) -} diff --git a/vendor/github.com/libp2p/go-libp2p-core/test/errors.go b/vendor/github.com/libp2p/go-libp2p-core/test/errors.go deleted file mode 100644 index 82a3e696f..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/test/errors.go +++ /dev/null @@ -1,19 +0,0 @@ -package test - -import ( - "testing" -) - -func AssertNilError(t *testing.T, err error) { - t.Helper() - if err != nil { - t.Errorf("unexpected error: %v", err) - } -} - -func ExpectError(t *testing.T, err error, msg string) { - t.Helper() - if err == nil { - t.Error(msg) - } -} diff --git a/vendor/github.com/libp2p/go-libp2p-core/test/peer.go b/vendor/github.com/libp2p/go-libp2p-core/test/peer.go deleted file mode 100644 index b95639fe2..000000000 --- a/vendor/github.com/libp2p/go-libp2p-core/test/peer.go +++ /dev/null @@ -1,25 +0,0 @@ -package test - -import ( - "math/rand" - "testing" - - "github.com/libp2p/go-libp2p-core/peer" - - mh "github.com/multiformats/go-multihash" -) - -func RandPeerID() (peer.ID, error) { - buf := make([]byte, 16) - rand.Read(buf) - h, _ := mh.Sum(buf, mh.SHA2_256, -1) - return peer.ID(h), nil -} - -func RandPeerIDFatal(t testing.TB) peer.ID { - p, err := RandPeerID() - if err != nil { - t.Fatal(err) - } - return p -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/.gitignore b/vendor/github.com/libp2p/go-libp2p-peerstore/.gitignore deleted file mode 100644 index bea702c06..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.swp -cover.out diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/LICENSE b/vendor/github.com/libp2p/go-libp2p-peerstore/LICENSE deleted file mode 100644 index 26100332b..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Jeromy Johnson - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/README.md b/vendor/github.com/libp2p/go-libp2p-peerstore/README.md deleted file mode 100644 index 0ad7cf978..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# go-libp2p-peerstore -[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai) -[![](https://img.shields.io/badge/project-libp2p-yellow.svg?style=flat-square)](https://libp2p.io/) -[![](https://img.shields.io/badge/freenode-%23libp2p-yellow.svg?style=flat-square)](http://webchat.freenode.net/?channels=%23libp2p) -[![GoDoc](https://godoc.org/github.com/libp2p/go-libp2p-peerstore?status.svg)](https://godoc.org/github.com/libp2p/go-libp2p-peerstore) -[![Coverage Status](https://coveralls.io/repos/github/libp2p/go-libp2p-peerstore/badge.svg?branch=master)](https://coveralls.io/github/libp2p/go-libp2p-peerstore?branch=master) -[![Build Status](https://travis-ci.org/libp2p/go-libp2p-peerstore.svg?branch=master)](https://travis-ci.org/libp2p/go-libp2p-peerstore) -[![Discourse posts](https://img.shields.io/discourse/https/discuss.libp2p.io/posts.svg)](https://discuss.libp2p.io) - -> An object to manage peers, their addresses, and other metadata about them. - -## Install - -```sh -go get github.com/libp2p/go-libp2p-peerstore -``` - -## Usage - -Check out the [GoDocs](https://godoc.org/github.com/libp2p/go-libp2p-peerstore). - -## Contribute - -Feel free to join in. All welcome. Open an [issue](https://github.com/ipfs/go-libp2p-peerstore/issues)! - -This repository falls under the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md). - -### Want to hack on IPFS? - -[![](https://cdn.rawgit.com/jbenet/contribute-ipfs-gif/master/img/contribute.gif)](https://github.com/ipfs/community/blob/master/CONTRIBUTING.md) - -## License -MIT - ---- - -The last gx published version of this module was: 2.0.19: QmaCTz9RkrU13bm9kMB54f7atgqM4qkjDZpRwRoJiWXEqs diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/codecov.yml b/vendor/github.com/libp2p/go-libp2p-peerstore/codecov.yml deleted file mode 100644 index 96dcfd789..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/codecov.yml +++ /dev/null @@ -1,5 +0,0 @@ -coverage: - range: "50...100" -comment: off -ignore: - - "pb/*.pb.go" \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/Makefile b/vendor/github.com/libp2p/go-libp2p-peerstore/pb/Makefile deleted file mode 100644 index 51e71f89f..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -PB = $(wildcard *.proto) -GO = $(PB:.proto=.pb.go) - -all: $(GO) - -%.pb.go: %.proto - protoc --proto_path=$(GOPATH)/src:. --gogofaster_out=. $< - -clean: - rm -f *.pb.go - -.PHONY: clean \ No newline at end of file diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/custom.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pb/custom.go deleted file mode 100644 index 41784a4f6..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/custom.go +++ /dev/null @@ -1,110 +0,0 @@ -package pstore_pb - -import ( - "encoding/json" - - proto "github.com/gogo/protobuf/proto" - peer "github.com/libp2p/go-libp2p-core/peer" - pt "github.com/libp2p/go-libp2p-core/test" - ma "github.com/multiformats/go-multiaddr" -) - -// customGogoType aggregates the interfaces that custom Gogo types need to implement. -// it is only used for type assertions. -type customGogoType interface { - proto.Marshaler - proto.Unmarshaler - json.Marshaler - json.Unmarshaler - proto.Sizer -} - -// ProtoAddr is a custom type used by gogo to serde raw peer IDs into the peer.ID type, and back. -type ProtoPeerID struct { - peer.ID -} - -var _ customGogoType = (*ProtoPeerID)(nil) - -func (id ProtoPeerID) Marshal() ([]byte, error) { - return []byte(id.ID), nil -} - -func (id ProtoPeerID) MarshalTo(data []byte) (n int, err error) { - return copy(data, []byte(id.ID)), nil -} - -func (id ProtoPeerID) MarshalJSON() ([]byte, error) { - m, _ := id.Marshal() - return json.Marshal(m) -} - -func (id *ProtoPeerID) Unmarshal(data []byte) (err error) { - id.ID = peer.ID(string(data)) - return nil -} - -func (id *ProtoPeerID) UnmarshalJSON(data []byte) error { - var v []byte - err := json.Unmarshal(data, &v) - if err != nil { - return err - } - return id.Unmarshal(v) -} - -func (id ProtoPeerID) Size() int { - return len([]byte(id.ID)) -} - -// ProtoAddr is a custom type used by gogo to serde raw multiaddresses into the ma.Multiaddr type, and back. -type ProtoAddr struct { - ma.Multiaddr -} - -var _ customGogoType = (*ProtoAddr)(nil) - -func (a ProtoAddr) Marshal() ([]byte, error) { - return a.Bytes(), nil -} - -func (a ProtoAddr) MarshalTo(data []byte) (n int, err error) { - return copy(data, a.Bytes()), nil -} - -func (a ProtoAddr) MarshalJSON() ([]byte, error) { - m, _ := a.Marshal() - return json.Marshal(m) -} - -func (a *ProtoAddr) Unmarshal(data []byte) (err error) { - a.Multiaddr, err = ma.NewMultiaddrBytes(data) - return err -} - -func (a *ProtoAddr) UnmarshalJSON(data []byte) error { - v := new([]byte) - err := json.Unmarshal(data, v) - if err != nil { - return err - } - return a.Unmarshal(*v) -} - -func (a ProtoAddr) Size() int { - return len(a.Bytes()) -} - -// NewPopulatedProtoAddr generates a populated instance of the custom gogo type ProtoAddr. -// It is required by gogo-generated tests. -func NewPopulatedProtoAddr(r randyPstore) *ProtoAddr { - a, _ := ma.NewMultiaddr("/ip4/123.123.123.123/tcp/7001") - return &ProtoAddr{Multiaddr: a} -} - -// NewPopulatedProtoPeerID generates a populated instance of the custom gogo type ProtoPeerID. -// It is required by gogo-generated tests. -func NewPopulatedProtoPeerID(r randyPstore) *ProtoPeerID { - id, _ := pt.RandPeerID() - return &ProtoPeerID{ID: id} -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.pb.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.pb.go deleted file mode 100644 index e9d7dfda6..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.pb.go +++ /dev/null @@ -1,1027 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: pstore.proto - -package pstore_pb - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// AddrBookRecord represents a record for a peer in the address book. -type AddrBookRecord struct { - // The peer ID. - Id *ProtoPeerID `protobuf:"bytes,1,opt,name=id,proto3,customtype=ProtoPeerID" json:"id,omitempty"` - // The multiaddresses. This is a sorted list where element 0 expires the soonest. - Addrs []*AddrBookRecord_AddrEntry `protobuf:"bytes,2,rep,name=addrs,proto3" json:"addrs,omitempty"` - // The most recently received signed PeerRecord. - CertifiedRecord *AddrBookRecord_CertifiedRecord `protobuf:"bytes,3,opt,name=certified_record,json=certifiedRecord,proto3" json:"certified_record,omitempty"` -} - -func (m *AddrBookRecord) Reset() { *m = AddrBookRecord{} } -func (m *AddrBookRecord) String() string { return proto.CompactTextString(m) } -func (*AddrBookRecord) ProtoMessage() {} -func (*AddrBookRecord) Descriptor() ([]byte, []int) { - return fileDescriptor_f96873690e08a98f, []int{0} -} -func (m *AddrBookRecord) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AddrBookRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_AddrBookRecord.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *AddrBookRecord) XXX_Merge(src proto.Message) { - xxx_messageInfo_AddrBookRecord.Merge(m, src) -} -func (m *AddrBookRecord) XXX_Size() int { - return m.Size() -} -func (m *AddrBookRecord) XXX_DiscardUnknown() { - xxx_messageInfo_AddrBookRecord.DiscardUnknown(m) -} - -var xxx_messageInfo_AddrBookRecord proto.InternalMessageInfo - -func (m *AddrBookRecord) GetAddrs() []*AddrBookRecord_AddrEntry { - if m != nil { - return m.Addrs - } - return nil -} - -func (m *AddrBookRecord) GetCertifiedRecord() *AddrBookRecord_CertifiedRecord { - if m != nil { - return m.CertifiedRecord - } - return nil -} - -// AddrEntry represents a single multiaddress. -type AddrBookRecord_AddrEntry struct { - Addr *ProtoAddr `protobuf:"bytes,1,opt,name=addr,proto3,customtype=ProtoAddr" json:"addr,omitempty"` - // The point in time when this address expires. - Expiry int64 `protobuf:"varint,2,opt,name=expiry,proto3" json:"expiry,omitempty"` - // The original TTL of this address. - Ttl int64 `protobuf:"varint,3,opt,name=ttl,proto3" json:"ttl,omitempty"` -} - -func (m *AddrBookRecord_AddrEntry) Reset() { *m = AddrBookRecord_AddrEntry{} } -func (m *AddrBookRecord_AddrEntry) String() string { return proto.CompactTextString(m) } -func (*AddrBookRecord_AddrEntry) ProtoMessage() {} -func (*AddrBookRecord_AddrEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_f96873690e08a98f, []int{0, 0} -} -func (m *AddrBookRecord_AddrEntry) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AddrBookRecord_AddrEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_AddrBookRecord_AddrEntry.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *AddrBookRecord_AddrEntry) XXX_Merge(src proto.Message) { - xxx_messageInfo_AddrBookRecord_AddrEntry.Merge(m, src) -} -func (m *AddrBookRecord_AddrEntry) XXX_Size() int { - return m.Size() -} -func (m *AddrBookRecord_AddrEntry) XXX_DiscardUnknown() { - xxx_messageInfo_AddrBookRecord_AddrEntry.DiscardUnknown(m) -} - -var xxx_messageInfo_AddrBookRecord_AddrEntry proto.InternalMessageInfo - -func (m *AddrBookRecord_AddrEntry) GetExpiry() int64 { - if m != nil { - return m.Expiry - } - return 0 -} - -func (m *AddrBookRecord_AddrEntry) GetTtl() int64 { - if m != nil { - return m.Ttl - } - return 0 -} - -// CertifiedRecord contains a serialized signed PeerRecord used to -// populate the signedAddrs list. -type AddrBookRecord_CertifiedRecord struct { - // The Seq counter from the signed PeerRecord envelope - Seq uint64 `protobuf:"varint,1,opt,name=seq,proto3" json:"seq,omitempty"` - // The serialized bytes of the SignedEnvelope containing the PeerRecord. - Raw []byte `protobuf:"bytes,2,opt,name=raw,proto3" json:"raw,omitempty"` -} - -func (m *AddrBookRecord_CertifiedRecord) Reset() { *m = AddrBookRecord_CertifiedRecord{} } -func (m *AddrBookRecord_CertifiedRecord) String() string { return proto.CompactTextString(m) } -func (*AddrBookRecord_CertifiedRecord) ProtoMessage() {} -func (*AddrBookRecord_CertifiedRecord) Descriptor() ([]byte, []int) { - return fileDescriptor_f96873690e08a98f, []int{0, 1} -} -func (m *AddrBookRecord_CertifiedRecord) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *AddrBookRecord_CertifiedRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_AddrBookRecord_CertifiedRecord.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *AddrBookRecord_CertifiedRecord) XXX_Merge(src proto.Message) { - xxx_messageInfo_AddrBookRecord_CertifiedRecord.Merge(m, src) -} -func (m *AddrBookRecord_CertifiedRecord) XXX_Size() int { - return m.Size() -} -func (m *AddrBookRecord_CertifiedRecord) XXX_DiscardUnknown() { - xxx_messageInfo_AddrBookRecord_CertifiedRecord.DiscardUnknown(m) -} - -var xxx_messageInfo_AddrBookRecord_CertifiedRecord proto.InternalMessageInfo - -func (m *AddrBookRecord_CertifiedRecord) GetSeq() uint64 { - if m != nil { - return m.Seq - } - return 0 -} - -func (m *AddrBookRecord_CertifiedRecord) GetRaw() []byte { - if m != nil { - return m.Raw - } - return nil -} - -func init() { - proto.RegisterType((*AddrBookRecord)(nil), "pstore.pb.AddrBookRecord") - proto.RegisterType((*AddrBookRecord_AddrEntry)(nil), "pstore.pb.AddrBookRecord.AddrEntry") - proto.RegisterType((*AddrBookRecord_CertifiedRecord)(nil), "pstore.pb.AddrBookRecord.CertifiedRecord") -} - -func init() { proto.RegisterFile("pstore.proto", fileDescriptor_f96873690e08a98f) } - -var fileDescriptor_f96873690e08a98f = []byte{ - // 322 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x28, 0x2e, 0xc9, - 0x2f, 0x4a, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0xf1, 0x92, 0xa4, 0x74, 0xd3, - 0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1, - 0x2a, 0x92, 0x4a, 0xd3, 0xc0, 0x3c, 0x30, 0x07, 0xcc, 0x82, 0xe8, 0x54, 0xba, 0xcc, 0xc4, 0xc5, - 0xe7, 0x98, 0x92, 0x52, 0xe4, 0x94, 0x9f, 0x9f, 0x1d, 0x94, 0x9a, 0x9c, 0x5f, 0x94, 0x22, 0x24, - 0xcf, 0xc5, 0x94, 0x99, 0x22, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0xe3, 0xc4, 0x7f, 0xeb, 0x9e, 0x3c, - 0x77, 0x00, 0x48, 0x65, 0x40, 0x6a, 0x6a, 0x91, 0xa7, 0x4b, 0x10, 0x53, 0x66, 0x8a, 0x90, 0x25, - 0x17, 0x6b, 0x62, 0x4a, 0x4a, 0x51, 0xb1, 0x04, 0x93, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0xb2, 0x1e, - 0xdc, 0x76, 0x3d, 0x54, 0xa3, 0xc0, 0x5c, 0xd7, 0xbc, 0x92, 0xa2, 0xca, 0x20, 0x88, 0x0e, 0xa1, - 0x10, 0x2e, 0x81, 0xe4, 0xd4, 0xa2, 0x92, 0xcc, 0xb4, 0xcc, 0xd4, 0x94, 0xf8, 0x22, 0xb0, 0x22, - 0x09, 0x66, 0x05, 0x46, 0x0d, 0x6e, 0x23, 0x4d, 0xdc, 0xa6, 0x38, 0xc3, 0x74, 0x40, 0xf8, 0x41, - 0xfc, 0xc9, 0xa8, 0x02, 0x52, 0x11, 0x5c, 0x9c, 0x70, 0x9b, 0x84, 0x14, 0xb9, 0x58, 0x40, 0x76, - 0x41, 0x3d, 0xc0, 0x7b, 0xeb, 0x9e, 0x3c, 0x27, 0xd8, 0x03, 0x20, 0x15, 0x41, 0x60, 0x29, 0x21, - 0x31, 0x2e, 0xb6, 0xd4, 0x8a, 0x82, 0xcc, 0xa2, 0x4a, 0x09, 0x26, 0x05, 0x46, 0x0d, 0xe6, 0x20, - 0x28, 0x4f, 0x48, 0x80, 0x8b, 0xb9, 0xa4, 0x24, 0x07, 0xec, 0x20, 0xe6, 0x20, 0x10, 0x53, 0xca, - 0x94, 0x8b, 0x1f, 0xcd, 0x76, 0x90, 0xa2, 0xe2, 0xd4, 0x42, 0xb0, 0xf1, 0x2c, 0x41, 0x20, 0x26, - 0x48, 0xa4, 0x28, 0xb1, 0x1c, 0x6c, 0x16, 0x4f, 0x10, 0x88, 0xe9, 0xa4, 0xf0, 0xe3, 0xa1, 0x1c, - 0xe3, 0x81, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, - 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x90, 0xc4, - 0x06, 0x0e, 0x7e, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x29, 0xcd, 0xe8, 0xd4, 0xc8, 0x01, - 0x00, 0x00, -} - -func (m *AddrBookRecord) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AddrBookRecord) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AddrBookRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.CertifiedRecord != nil { - { - size, err := m.CertifiedRecord.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintPstore(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if len(m.Addrs) > 0 { - for iNdEx := len(m.Addrs) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Addrs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintPstore(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - } - if m.Id != nil { - { - size := m.Id.Size() - i -= size - if _, err := m.Id.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintPstore(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *AddrBookRecord_AddrEntry) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AddrBookRecord_AddrEntry) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AddrBookRecord_AddrEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.Ttl != 0 { - i = encodeVarintPstore(dAtA, i, uint64(m.Ttl)) - i-- - dAtA[i] = 0x18 - } - if m.Expiry != 0 { - i = encodeVarintPstore(dAtA, i, uint64(m.Expiry)) - i-- - dAtA[i] = 0x10 - } - if m.Addr != nil { - { - size := m.Addr.Size() - i -= size - if _, err := m.Addr.MarshalTo(dAtA[i:]); err != nil { - return 0, err - } - i = encodeVarintPstore(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *AddrBookRecord_CertifiedRecord) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *AddrBookRecord_CertifiedRecord) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *AddrBookRecord_CertifiedRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Raw) > 0 { - i -= len(m.Raw) - copy(dAtA[i:], m.Raw) - i = encodeVarintPstore(dAtA, i, uint64(len(m.Raw))) - i-- - dAtA[i] = 0x12 - } - if m.Seq != 0 { - i = encodeVarintPstore(dAtA, i, uint64(m.Seq)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func encodeVarintPstore(dAtA []byte, offset int, v uint64) int { - offset -= sovPstore(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func NewPopulatedAddrBookRecord(r randyPstore, easy bool) *AddrBookRecord { - this := &AddrBookRecord{} - this.Id = NewPopulatedProtoPeerID(r) - if r.Intn(5) != 0 { - v1 := r.Intn(5) - this.Addrs = make([]*AddrBookRecord_AddrEntry, v1) - for i := 0; i < v1; i++ { - this.Addrs[i] = NewPopulatedAddrBookRecord_AddrEntry(r, easy) - } - } - if r.Intn(5) != 0 { - this.CertifiedRecord = NewPopulatedAddrBookRecord_CertifiedRecord(r, easy) - } - if !easy && r.Intn(10) != 0 { - } - return this -} - -func NewPopulatedAddrBookRecord_AddrEntry(r randyPstore, easy bool) *AddrBookRecord_AddrEntry { - this := &AddrBookRecord_AddrEntry{} - this.Addr = NewPopulatedProtoAddr(r) - this.Expiry = int64(r.Int63()) - if r.Intn(2) == 0 { - this.Expiry *= -1 - } - this.Ttl = int64(r.Int63()) - if r.Intn(2) == 0 { - this.Ttl *= -1 - } - if !easy && r.Intn(10) != 0 { - } - return this -} - -func NewPopulatedAddrBookRecord_CertifiedRecord(r randyPstore, easy bool) *AddrBookRecord_CertifiedRecord { - this := &AddrBookRecord_CertifiedRecord{} - this.Seq = uint64(uint64(r.Uint32())) - v2 := r.Intn(100) - this.Raw = make([]byte, v2) - for i := 0; i < v2; i++ { - this.Raw[i] = byte(r.Intn(256)) - } - if !easy && r.Intn(10) != 0 { - } - return this -} - -type randyPstore interface { - Float32() float32 - Float64() float64 - Int63() int64 - Int31() int32 - Uint32() uint32 - Intn(n int) int -} - -func randUTF8RunePstore(r randyPstore) rune { - ru := r.Intn(62) - if ru < 10 { - return rune(ru + 48) - } else if ru < 36 { - return rune(ru + 55) - } - return rune(ru + 61) -} -func randStringPstore(r randyPstore) string { - v3 := r.Intn(100) - tmps := make([]rune, v3) - for i := 0; i < v3; i++ { - tmps[i] = randUTF8RunePstore(r) - } - return string(tmps) -} -func randUnrecognizedPstore(r randyPstore, maxFieldNumber int) (dAtA []byte) { - l := r.Intn(5) - for i := 0; i < l; i++ { - wire := r.Intn(4) - if wire == 3 { - wire = 5 - } - fieldNumber := maxFieldNumber + r.Intn(100) - dAtA = randFieldPstore(dAtA, r, fieldNumber, wire) - } - return dAtA -} -func randFieldPstore(dAtA []byte, r randyPstore, fieldNumber int, wire int) []byte { - key := uint32(fieldNumber)<<3 | uint32(wire) - switch wire { - case 0: - dAtA = encodeVarintPopulatePstore(dAtA, uint64(key)) - v4 := r.Int63() - if r.Intn(2) == 0 { - v4 *= -1 - } - dAtA = encodeVarintPopulatePstore(dAtA, uint64(v4)) - case 1: - dAtA = encodeVarintPopulatePstore(dAtA, uint64(key)) - dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) - case 2: - dAtA = encodeVarintPopulatePstore(dAtA, uint64(key)) - ll := r.Intn(100) - dAtA = encodeVarintPopulatePstore(dAtA, uint64(ll)) - for j := 0; j < ll; j++ { - dAtA = append(dAtA, byte(r.Intn(256))) - } - default: - dAtA = encodeVarintPopulatePstore(dAtA, uint64(key)) - dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) - } - return dAtA -} -func encodeVarintPopulatePstore(dAtA []byte, v uint64) []byte { - for v >= 1<<7 { - dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80)) - v >>= 7 - } - dAtA = append(dAtA, uint8(v)) - return dAtA -} -func (m *AddrBookRecord) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Id != nil { - l = m.Id.Size() - n += 1 + l + sovPstore(uint64(l)) - } - if len(m.Addrs) > 0 { - for _, e := range m.Addrs { - l = e.Size() - n += 1 + l + sovPstore(uint64(l)) - } - } - if m.CertifiedRecord != nil { - l = m.CertifiedRecord.Size() - n += 1 + l + sovPstore(uint64(l)) - } - return n -} - -func (m *AddrBookRecord_AddrEntry) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Addr != nil { - l = m.Addr.Size() - n += 1 + l + sovPstore(uint64(l)) - } - if m.Expiry != 0 { - n += 1 + sovPstore(uint64(m.Expiry)) - } - if m.Ttl != 0 { - n += 1 + sovPstore(uint64(m.Ttl)) - } - return n -} - -func (m *AddrBookRecord_CertifiedRecord) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Seq != 0 { - n += 1 + sovPstore(uint64(m.Seq)) - } - l = len(m.Raw) - if l > 0 { - n += 1 + l + sovPstore(uint64(l)) - } - return n -} - -func sovPstore(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozPstore(x uint64) (n int) { - return sovPstore(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *AddrBookRecord) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AddrBookRecord: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AddrBookRecord: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthPstore - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthPstore - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v ProtoPeerID - m.Id = &v - if err := m.Id.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Addrs", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthPstore - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthPstore - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Addrs = append(m.Addrs, &AddrBookRecord_AddrEntry{}) - if err := m.Addrs[len(m.Addrs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CertifiedRecord", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthPstore - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthPstore - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.CertifiedRecord == nil { - m.CertifiedRecord = &AddrBookRecord_CertifiedRecord{} - } - if err := m.CertifiedRecord.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPstore(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPstore - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AddrBookRecord_AddrEntry) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: AddrEntry: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: AddrEntry: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Addr", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthPstore - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthPstore - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - var v ProtoAddr - m.Addr = &v - if err := m.Addr.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Expiry", wireType) - } - m.Expiry = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Expiry |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) - } - m.Ttl = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Ttl |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipPstore(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPstore - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *AddrBookRecord_CertifiedRecord) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: CertifiedRecord: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: CertifiedRecord: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Seq", wireType) - } - m.Seq = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Seq |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Raw", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowPstore - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthPstore - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthPstore - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Raw = append(m.Raw[:0], dAtA[iNdEx:postIndex]...) - if m.Raw == nil { - m.Raw = []byte{} - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipPstore(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthPstore - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipPstore(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPstore - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPstore - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowPstore - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthPstore - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupPstore - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthPstore - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthPstore = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowPstore = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupPstore = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.proto b/vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.proto deleted file mode 100644 index 0d1abd1da..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pb/pstore.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto3"; -package pstore.pb; - -import "github.com/gogo/protobuf/gogoproto/gogo.proto"; - -option (gogoproto.benchgen_all) = true; -option (gogoproto.populate_all) = true; - -// AddrBookRecord represents a record for a peer in the address book. -message AddrBookRecord { - // The peer ID. - bytes id = 1 [(gogoproto.customtype) = "ProtoPeerID"]; - - // The multiaddresses. This is a sorted list where element 0 expires the soonest. - repeated AddrEntry addrs = 2; - - // The most recently received signed PeerRecord. - CertifiedRecord certified_record = 3; - - // AddrEntry represents a single multiaddress. - message AddrEntry { - bytes addr = 1 [(gogoproto.customtype) = "ProtoAddr"]; - - // The point in time when this address expires. - int64 expiry = 2; - - // The original TTL of this address. - int64 ttl = 3; - } - - // CertifiedRecord contains a serialized signed PeerRecord used to - // populate the signedAddrs list. - message CertifiedRecord { - // The Seq counter from the signed PeerRecord envelope - uint64 seq = 1; - - // The serialized bytes of the SignedEnvelope containing the PeerRecord. - bytes raw = 2; - } -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book.go deleted file mode 100644 index 6c7bed79a..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book.go +++ /dev/null @@ -1,605 +0,0 @@ -package pstoreds - -import ( - "context" - "fmt" - "sort" - "sync" - "time" - - ds "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/query" - logging "github.com/ipfs/go-log/v2" - - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" - pb "github.com/libp2p/go-libp2p-peerstore/pb" - "github.com/libp2p/go-libp2p-peerstore/pstoremem" - - lru "github.com/hashicorp/golang-lru" - b32 "github.com/multiformats/go-base32" - ma "github.com/multiformats/go-multiaddr" -) - -type ttlWriteMode int - -const ( - ttlOverride ttlWriteMode = iota - ttlExtend -) - -var ( - log = logging.Logger("peerstore/ds") - - // Peer addresses are stored db key pattern: - // /peers/addrs/ - addrBookBase = ds.NewKey("/peers/addrs") -) - -// addrsRecord decorates the AddrBookRecord with locks and metadata. -type addrsRecord struct { - sync.RWMutex - *pb.AddrBookRecord - dirty bool -} - -// flush writes the record to the datastore by calling ds.Put, unless the record is -// marked for deletion, in which case we call ds.Delete. To be called within a lock. -func (r *addrsRecord) flush(write ds.Write) (err error) { - key := addrBookBase.ChildString(b32.RawStdEncoding.EncodeToString([]byte(r.Id.ID))) - - if len(r.Addrs) == 0 { - if err = write.Delete(context.TODO(), key); err == nil { - r.dirty = false - } - return err - } - - data, err := r.Marshal() - if err != nil { - return err - } - if err = write.Put(context.TODO(), key, data); err != nil { - return err - } - // write succeeded; record is no longer dirty. - r.dirty = false - return nil -} - -// clean is called on records to perform housekeeping. The return value indicates if the record was changed -// as a result of this call. -// -// clean does the following: -// * sorts addresses by expiration (soonest expiring first). -// * removes expired addresses. -// -// It short-circuits optimistically when there's nothing to do. -// -// clean is called from several points: -// * when accessing an entry. -// * when performing periodic GC. -// * after an entry has been modified (e.g. addresses have been added or removed, TTLs updated, etc.) -// -// If the return value is true, the caller should perform a flush immediately to sync the record with the store. -func (r *addrsRecord) clean(now time.Time) (chgd bool) { - nowUnix := now.Unix() - addrsLen := len(r.Addrs) - - if !r.dirty && !r.hasExpiredAddrs(nowUnix) { - // record is not dirty, and we have no expired entries to purge. - return false - } - - if addrsLen == 0 { - // this is a ghost record; let's signal it has to be written. - // flush() will take care of doing the deletion. - return true - } - - if r.dirty && addrsLen > 1 { - sort.Slice(r.Addrs, func(i, j int) bool { - return r.Addrs[i].Expiry < r.Addrs[j].Expiry - }) - } - - r.Addrs = removeExpired(r.Addrs, nowUnix) - - return r.dirty || len(r.Addrs) != addrsLen -} - -func (r *addrsRecord) hasExpiredAddrs(now int64) bool { - if len(r.Addrs) > 0 && r.Addrs[0].Expiry <= now { - return true - } - return false -} - -func removeExpired(entries []*pb.AddrBookRecord_AddrEntry, now int64) []*pb.AddrBookRecord_AddrEntry { - // since addresses are sorted by expiration, we find the first - // survivor and split the slice on its index. - pivot := -1 - for i, addr := range entries { - if addr.Expiry > now { - break - } - pivot = i - } - - return entries[pivot+1:] -} - -// dsAddrBook is an address book backed by a Datastore with a GC procedure to purge expired entries. It uses an -// in-memory address stream manager. See the NewAddrBook for more information. -type dsAddrBook struct { - ctx context.Context - opts Options - - cache cache - ds ds.Batching - gc *dsAddrBookGc - subsManager *pstoremem.AddrSubManager - - // controls children goroutine lifetime. - childrenDone sync.WaitGroup - cancelFn func() - - clock clock -} - -type clock interface { - Now() time.Time - After(d time.Duration) <-chan time.Time -} - -type realclock struct{} - -func (rc realclock) Now() time.Time { - return time.Now() -} - -func (rc realclock) After(d time.Duration) <-chan time.Time { - return time.After(d) -} - -var _ pstore.AddrBook = (*dsAddrBook)(nil) -var _ pstore.CertifiedAddrBook = (*dsAddrBook)(nil) - -// NewAddrBook initializes a new datastore-backed address book. It serves as a drop-in replacement for pstoremem -// (memory-backed peerstore), and works with any datastore implementing the ds.Batching interface. -// -// Addresses and peer records are serialized into protobuf, storing one datastore entry per peer, along with metadata -// to control address expiration. To alleviate disk access and serde overhead, we internally use a read/write-through -// ARC cache, the size of which is adjustable via Options.CacheSize. -// -// The user has a choice of two GC algorithms: -// -// - lookahead GC: minimises the amount of full store traversals by maintaining a time-indexed list of entries that -// need to be visited within the period specified in Options.GCLookaheadInterval. This is useful in scenarios with -// considerable TTL variance, coupled with datastores whose native iterators return entries in lexicographical key -// order. Enable this mode by passing a value Options.GCLookaheadInterval > 0. Lookahead windows are jumpy, not -// sliding. Purges operate exclusively over the lookahead window with periodicity Options.GCPurgeInterval. -// -// - full-purge GC (default): performs a full visit of the store with periodicity Options.GCPurgeInterval. Useful when -// the range of possible TTL values is small and the values themselves are also extreme, e.g. 10 minutes or -// permanent, popular values used in other libp2p modules. In this cited case, optimizing with lookahead windows -// makes little sense. -func NewAddrBook(ctx context.Context, store ds.Batching, opts Options) (ab *dsAddrBook, err error) { - ctx, cancelFn := context.WithCancel(ctx) - ab = &dsAddrBook{ - ctx: ctx, - ds: store, - opts: opts, - cancelFn: cancelFn, - subsManager: pstoremem.NewAddrSubManager(), - clock: realclock{}, - } - - if opts.Clock != nil { - ab.clock = opts.Clock - } - - if opts.CacheSize > 0 { - if ab.cache, err = lru.NewARC(int(opts.CacheSize)); err != nil { - return nil, err - } - } else { - ab.cache = new(noopCache) - } - - if ab.gc, err = newAddressBookGc(ctx, ab); err != nil { - return nil, err - } - - return ab, nil -} - -func (ab *dsAddrBook) Close() error { - ab.cancelFn() - ab.childrenDone.Wait() - return nil -} - -// loadRecord is a read-through fetch. It fetches a record from cache, falling back to the -// datastore upon a miss, and returning a newly initialized record if the peer doesn't exist. -// -// loadRecord calls clean() on an existing record before returning it. If the record changes -// as a result and the update argument is true, the resulting state is saved in the datastore. -// -// If the cache argument is true, the record is inserted in the cache when loaded from the datastore. -func (ab *dsAddrBook) loadRecord(id peer.ID, cache bool, update bool) (pr *addrsRecord, err error) { - if e, ok := ab.cache.Get(id); ok { - pr = e.(*addrsRecord) - pr.Lock() - defer pr.Unlock() - - if pr.clean(ab.clock.Now()) && update { - err = pr.flush(ab.ds) - } - return pr, err - } - - pr = &addrsRecord{AddrBookRecord: &pb.AddrBookRecord{}} - key := addrBookBase.ChildString(b32.RawStdEncoding.EncodeToString([]byte(id))) - data, err := ab.ds.Get(context.TODO(), key) - - switch err { - case ds.ErrNotFound: - err = nil - pr.Id = &pb.ProtoPeerID{ID: id} - case nil: - if err = pr.Unmarshal(data); err != nil { - return nil, err - } - // this record is new and local for now (not in cache), so we don't need to lock. - if pr.clean(ab.clock.Now()) && update { - err = pr.flush(ab.ds) - } - default: - return nil, err - } - - if cache { - ab.cache.Add(id, pr) - } - return pr, err -} - -// AddAddr will add a new address if it's not already in the AddrBook. -func (ab *dsAddrBook) AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration) { - ab.AddAddrs(p, []ma.Multiaddr{addr}, ttl) -} - -// AddAddrs will add many new addresses if they're not already in the AddrBook. -func (ab *dsAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) { - if ttl <= 0 { - return - } - addrs = cleanAddrs(addrs) - ab.setAddrs(p, addrs, ttl, ttlExtend, false) -} - -// ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in -// a record.Envelope), which will expire after the given TTL. -// See https://godoc.org/github.com/libp2p/go-libp2p-core/peerstore#CertifiedAddrBook for more details. -func (ab *dsAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, ttl time.Duration) (bool, error) { - r, err := recordEnvelope.Record() - if err != nil { - return false, err - } - rec, ok := r.(*peer.PeerRecord) - if !ok { - return false, fmt.Errorf("envelope did not contain PeerRecord") - } - if !rec.PeerID.MatchesPublicKey(recordEnvelope.PublicKey) { - return false, fmt.Errorf("signing key does not match PeerID in PeerRecord") - } - - // ensure that the seq number from envelope is >= any previously received seq no - // update when equal to extend the ttls - if ab.latestPeerRecordSeq(rec.PeerID) > rec.Seq { - return false, nil - } - - addrs := cleanAddrs(rec.Addrs) - err = ab.setAddrs(rec.PeerID, addrs, ttl, ttlExtend, true) - if err != nil { - return false, err - } - - err = ab.storeSignedPeerRecord(rec.PeerID, recordEnvelope, rec) - if err != nil { - return false, err - } - return true, nil -} - -func (ab *dsAddrBook) latestPeerRecordSeq(p peer.ID) uint64 { - pr, err := ab.loadRecord(p, true, false) - if err != nil { - // We ignore the error because we don't want to fail storing a new record in this - // case. - log.Errorw("unable to load record", "peer", p, "error", err) - return 0 - } - pr.RLock() - defer pr.RUnlock() - - if len(pr.Addrs) == 0 || pr.CertifiedRecord == nil || len(pr.CertifiedRecord.Raw) == 0 { - return 0 - } - return pr.CertifiedRecord.Seq -} - -func (ab *dsAddrBook) storeSignedPeerRecord(p peer.ID, envelope *record.Envelope, rec *peer.PeerRecord) error { - envelopeBytes, err := envelope.Marshal() - if err != nil { - return err - } - // reload record and add routing state - // this has to be done after we add the addresses, since if - // we try to flush a datastore record with no addresses, - // it will just get deleted - pr, err := ab.loadRecord(p, true, false) - if err != nil { - return err - } - pr.Lock() - defer pr.Unlock() - pr.CertifiedRecord = &pb.AddrBookRecord_CertifiedRecord{ - Seq: rec.Seq, - Raw: envelopeBytes, - } - pr.dirty = true - err = pr.flush(ab.ds) - return err -} - -// GetPeerRecord returns a record.Envelope containing a peer.PeerRecord for the -// given peer id, if one exists. -// Returns nil if no signed PeerRecord exists for the peer. -func (ab *dsAddrBook) GetPeerRecord(p peer.ID) *record.Envelope { - pr, err := ab.loadRecord(p, true, false) - if err != nil { - log.Errorf("unable to load record for peer %s: %v", p.Pretty(), err) - return nil - } - pr.RLock() - defer pr.RUnlock() - if pr.CertifiedRecord == nil || len(pr.CertifiedRecord.Raw) == 0 || len(pr.Addrs) == 0 { - return nil - } - state, _, err := record.ConsumeEnvelope(pr.CertifiedRecord.Raw, peer.PeerRecordEnvelopeDomain) - if err != nil { - log.Errorf("error unmarshaling stored signed peer record for peer %s: %v", p.Pretty(), err) - return nil - } - return state -} - -// SetAddr will add or update the TTL of an address in the AddrBook. -func (ab *dsAddrBook) SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration) { - ab.SetAddrs(p, []ma.Multiaddr{addr}, ttl) -} - -// SetAddrs will add or update the TTLs of addresses in the AddrBook. -func (ab *dsAddrBook) SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) { - addrs = cleanAddrs(addrs) - if ttl <= 0 { - ab.deleteAddrs(p, addrs) - return - } - ab.setAddrs(p, addrs, ttl, ttlOverride, false) -} - -// UpdateAddrs will update any addresses for a given peer and TTL combination to -// have a new TTL. -func (ab *dsAddrBook) UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL time.Duration) { - pr, err := ab.loadRecord(p, true, false) - if err != nil { - log.Errorf("failed to update ttls for peer %s: %s\n", p.Pretty(), err) - return - } - - pr.Lock() - defer pr.Unlock() - - newExp := ab.clock.Now().Add(newTTL).Unix() - for _, entry := range pr.Addrs { - if entry.Ttl != int64(oldTTL) { - continue - } - entry.Ttl, entry.Expiry = int64(newTTL), newExp - pr.dirty = true - } - - if pr.clean(ab.clock.Now()) { - pr.flush(ab.ds) - } -} - -// Addrs returns all of the non-expired addresses for a given peer. -func (ab *dsAddrBook) Addrs(p peer.ID) []ma.Multiaddr { - pr, err := ab.loadRecord(p, true, true) - if err != nil { - log.Warn("failed to load peerstore entry for peer %v while querying addrs, err: %v", p, err) - return nil - } - - pr.RLock() - defer pr.RUnlock() - - addrs := make([]ma.Multiaddr, len(pr.Addrs)) - for i, a := range pr.Addrs { - addrs[i] = a.Addr - } - return addrs -} - -// Peers returns all of the peer IDs for which the AddrBook has addresses. -func (ab *dsAddrBook) PeersWithAddrs() peer.IDSlice { - ids, err := uniquePeerIds(ab.ds, addrBookBase, func(result query.Result) string { - return ds.RawKey(result.Key).Name() - }) - if err != nil { - log.Errorf("error while retrieving peers with addresses: %v", err) - } - return ids -} - -// AddrStream returns a channel on which all new addresses discovered for a -// given peer ID will be published. -func (ab *dsAddrBook) AddrStream(ctx context.Context, p peer.ID) <-chan ma.Multiaddr { - initial := ab.Addrs(p) - return ab.subsManager.AddrStream(ctx, p, initial) -} - -// ClearAddrs will delete all known addresses for a peer ID. -func (ab *dsAddrBook) ClearAddrs(p peer.ID) { - ab.cache.Remove(p) - - key := addrBookBase.ChildString(b32.RawStdEncoding.EncodeToString([]byte(p))) - if err := ab.ds.Delete(context.TODO(), key); err != nil { - log.Errorf("failed to clear addresses for peer %s: %v", p.Pretty(), err) - } -} - -func (ab *dsAddrBook) setAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, mode ttlWriteMode, signed bool) (err error) { - if len(addrs) == 0 { - return nil - } - - pr, err := ab.loadRecord(p, true, false) - if err != nil { - return fmt.Errorf("failed to load peerstore entry for peer %v while setting addrs, err: %v", p, err) - } - - pr.Lock() - defer pr.Unlock() - - // // if we have a signed PeerRecord, ignore attempts to add unsigned addrs - // if !signed && pr.CertifiedRecord != nil { - // return nil - // } - - newExp := ab.clock.Now().Add(ttl).Unix() - addrsMap := make(map[string]*pb.AddrBookRecord_AddrEntry, len(pr.Addrs)) - for _, addr := range pr.Addrs { - addrsMap[string(addr.Addr.Bytes())] = addr - } - - updateExisting := func(incoming ma.Multiaddr) *pb.AddrBookRecord_AddrEntry { - existingEntry := addrsMap[string(incoming.Bytes())] - if existingEntry == nil { - return nil - } - - switch mode { - case ttlOverride: - existingEntry.Ttl = int64(ttl) - existingEntry.Expiry = newExp - case ttlExtend: - if int64(ttl) > existingEntry.Ttl { - existingEntry.Ttl = int64(ttl) - } - if newExp > existingEntry.Expiry { - existingEntry.Expiry = newExp - } - default: - panic("BUG: unimplemented ttl mode") - } - return existingEntry - } - - var entries []*pb.AddrBookRecord_AddrEntry - for _, incoming := range addrs { - existingEntry := updateExisting(incoming) - - if existingEntry == nil { - // if signed { - // entries = append(entries, existingEntry) - // } - // } else { - // new addr, add & broadcast - entry := &pb.AddrBookRecord_AddrEntry{ - Addr: &pb.ProtoAddr{Multiaddr: incoming}, - Ttl: int64(ttl), - Expiry: newExp, - } - entries = append(entries, entry) - - // note: there's a minor chance that writing the record will fail, in which case we would've broadcast - // the addresses without persisting them. This is very unlikely and not much of an issue. - ab.subsManager.BroadcastAddr(p, incoming) - } - } - - // if signed { - // // when adding signed addrs, we want to keep _only_ the incoming addrs - // pr.Addrs = entries - // } else { - pr.Addrs = append(pr.Addrs, entries...) - // } - - pr.dirty = true - pr.clean(ab.clock.Now()) - return pr.flush(ab.ds) -} - -// deletes addresses in place, avoiding copies until we encounter the first deletion. -// does not preserve order, but entries are re-sorted before flushing to disk anyway. -func deleteInPlace(s []*pb.AddrBookRecord_AddrEntry, addrs []ma.Multiaddr) []*pb.AddrBookRecord_AddrEntry { - if s == nil || len(addrs) == 0 { - return s - } - survived := len(s) -Outer: - for i, addr := range s { - for _, del := range addrs { - if !addr.Addr.Equal(del) { - continue - } - survived-- - // if there are no survivors, bail out - if survived == 0 { - break Outer - } - s[i] = s[survived] - // we've already dealt with s[i], move to the next - continue Outer - } - } - return s[:survived] -} - -func (ab *dsAddrBook) deleteAddrs(p peer.ID, addrs []ma.Multiaddr) (err error) { - pr, err := ab.loadRecord(p, false, false) - if err != nil { - return fmt.Errorf("failed to load peerstore entry for peer %v while deleting addrs, err: %v", p, err) - } - - pr.Lock() - defer pr.Unlock() - - if pr.Addrs == nil { - return nil - } - - pr.Addrs = deleteInPlace(pr.Addrs, addrs) - - pr.dirty = true - pr.clean(ab.clock.Now()) - return pr.flush(ab.ds) -} - -func cleanAddrs(addrs []ma.Multiaddr) []ma.Multiaddr { - clean := make([]ma.Multiaddr, 0, len(addrs)) - for _, addr := range addrs { - if addr == nil { - continue - } - clean = append(clean, addr) - } - return clean -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book_gc.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book_gc.go deleted file mode 100644 index 99802173d..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/addr_book_gc.go +++ /dev/null @@ -1,410 +0,0 @@ -package pstoreds - -import ( - "context" - "fmt" - "strconv" - "time" - - ds "github.com/ipfs/go-datastore" - query "github.com/ipfs/go-datastore/query" - - peer "github.com/libp2p/go-libp2p-core/peer" - pb "github.com/libp2p/go-libp2p-peerstore/pb" - - b32 "github.com/multiformats/go-base32" -) - -var ( - // GC lookahead entries are stored in key pattern: - // /peers/gc/addrs// => nil - // in databases with lexicographical key order, this time-indexing allows us to visit - // only the timeslice we are interested in. - gcLookaheadBase = ds.NewKey("/peers/gc/addrs") - - // queries - purgeLookaheadQuery = query.Query{ - Prefix: gcLookaheadBase.String(), - Orders: []query.Order{query.OrderByFunction(orderByTimestampInKey)}, - KeysOnly: true, - } - - purgeStoreQuery = query.Query{ - Prefix: addrBookBase.String(), - Orders: []query.Order{query.OrderByKey{}}, - KeysOnly: false, - } - - populateLookaheadQuery = query.Query{ - Prefix: addrBookBase.String(), - Orders: []query.Order{query.OrderByKey{}}, - KeysOnly: true, - } -) - -// dsAddrBookGc is responsible for garbage collection in a datastore-backed address book. -type dsAddrBookGc struct { - ctx context.Context - ab *dsAddrBook - running chan struct{} - lookaheadEnabled bool - purgeFunc func() - currWindowEnd int64 -} - -func newAddressBookGc(ctx context.Context, ab *dsAddrBook) (*dsAddrBookGc, error) { - if ab.opts.GCPurgeInterval < 0 { - return nil, fmt.Errorf("negative GC purge interval provided: %s", ab.opts.GCPurgeInterval) - } - if ab.opts.GCLookaheadInterval < 0 { - return nil, fmt.Errorf("negative GC lookahead interval provided: %s", ab.opts.GCLookaheadInterval) - } - if ab.opts.GCInitialDelay < 0 { - return nil, fmt.Errorf("negative GC initial delay provided: %s", ab.opts.GCInitialDelay) - } - if ab.opts.GCLookaheadInterval > 0 && ab.opts.GCLookaheadInterval < ab.opts.GCPurgeInterval { - return nil, fmt.Errorf("lookahead interval must be larger than purge interval, respectively: %s, %s", - ab.opts.GCLookaheadInterval, ab.opts.GCPurgeInterval) - } - - lookaheadEnabled := ab.opts.GCLookaheadInterval > 0 - gc := &dsAddrBookGc{ - ctx: ctx, - ab: ab, - running: make(chan struct{}, 1), - lookaheadEnabled: lookaheadEnabled, - } - - if lookaheadEnabled { - gc.purgeFunc = gc.purgeLookahead - } else { - gc.purgeFunc = gc.purgeStore - } - - // do not start GC timers if purge is disabled; this GC can only be triggered manually. - if ab.opts.GCPurgeInterval > 0 { - gc.ab.childrenDone.Add(1) - go gc.background() - } - - return gc, nil -} - -// gc prunes expired addresses from the datastore at regular intervals. It should be spawned as a goroutine. -func (gc *dsAddrBookGc) background() { - defer gc.ab.childrenDone.Done() - - select { - case <-gc.ab.clock.After(gc.ab.opts.GCInitialDelay): - case <-gc.ab.ctx.Done(): - // yield if we have been cancelled/closed before the delay elapses. - return - } - - purgeTimer := time.NewTicker(gc.ab.opts.GCPurgeInterval) - defer purgeTimer.Stop() - - var lookaheadCh <-chan time.Time - if gc.lookaheadEnabled { - lookaheadTimer := time.NewTicker(gc.ab.opts.GCLookaheadInterval) - lookaheadCh = lookaheadTimer.C - gc.populateLookahead() // do a lookahead now - defer lookaheadTimer.Stop() - } - - for { - select { - case <-purgeTimer.C: - gc.purgeFunc() - - case <-lookaheadCh: - // will never trigger if lookahead is disabled (nil Duration). - gc.populateLookahead() - - case <-gc.ctx.Done(): - return - } - } -} - -// purgeCycle runs a single GC purge cycle. It operates within the lookahead window if lookahead is enabled; else it -// visits all entries in the datastore, deleting the addresses that have expired. -func (gc *dsAddrBookGc) purgeLookahead() { - select { - case gc.running <- struct{}{}: - defer func() { <-gc.running }() - default: - // yield if lookahead is running. - return - } - - var id peer.ID - record := &addrsRecord{AddrBookRecord: &pb.AddrBookRecord{}} // empty record to reuse and avoid allocs. - batch, err := newCyclicBatch(gc.ab.ds, defaultOpsPerCyclicBatch) - if err != nil { - log.Warnf("failed while creating batch to purge GC entries: %v", err) - } - - // This function drops an unparseable GC entry; this is for safety. It is an escape hatch in case - // we modify the format of keys going forward. If a user runs a new version against an old DB, - // if we don't clean up unparseable entries we'll end up accumulating garbage. - dropInError := func(key ds.Key, err error, msg string) { - if err != nil { - log.Warnf("failed while %s record with GC key: %v, err: %v; deleting", msg, key, err) - } - if err = batch.Delete(context.TODO(), key); err != nil { - log.Warnf("failed to delete corrupt GC lookahead entry: %v, err: %v", key, err) - } - } - - // This function drops a GC key if the entry is cleaned correctly. It may reschedule another visit - // if the next earliest expiry falls within the current window again. - dropOrReschedule := func(key ds.Key, ar *addrsRecord) { - if err := batch.Delete(context.TODO(), key); err != nil { - log.Warnf("failed to delete lookahead entry: %v, err: %v", key, err) - } - - // re-add the record if it needs to be visited again in this window. - if len(ar.Addrs) != 0 && ar.Addrs[0].Expiry <= gc.currWindowEnd { - gcKey := gcLookaheadBase.ChildString(fmt.Sprintf("%d/%s", ar.Addrs[0].Expiry, key.Name())) - if err := batch.Put(context.TODO(), gcKey, []byte{}); err != nil { - log.Warnf("failed to add new GC key: %v, err: %v", gcKey, err) - } - } - } - - results, err := gc.ab.ds.Query(context.TODO(), purgeLookaheadQuery) - if err != nil { - log.Warnf("failed while fetching entries to purge: %v", err) - return - } - defer results.Close() - - now := gc.ab.clock.Now().Unix() - - // keys: /peers/gc/addrs// - // values: nil - for result := range results.Next() { - gcKey := ds.RawKey(result.Key) - ts, err := strconv.ParseInt(gcKey.Parent().Name(), 10, 64) - if err != nil { - dropInError(gcKey, err, "parsing timestamp") - log.Warnf("failed while parsing timestamp from key: %v, err: %v", result.Key, err) - continue - } else if ts > now { - // this is an ordered cursor; when we hit an entry with a timestamp beyond now, we can break. - break - } - - idb32, err := b32.RawStdEncoding.DecodeString(gcKey.Name()) - if err != nil { - dropInError(gcKey, err, "parsing peer ID") - log.Warnf("failed while parsing b32 peer ID from key: %v, err: %v", result.Key, err) - continue - } - - id, err = peer.IDFromBytes(idb32) - if err != nil { - dropInError(gcKey, err, "decoding peer ID") - log.Warnf("failed while decoding peer ID from key: %v, err: %v", result.Key, err) - continue - } - - // if the record is in cache, we clean it and flush it if necessary. - if e, ok := gc.ab.cache.Peek(id); ok { - cached := e.(*addrsRecord) - cached.Lock() - if cached.clean(gc.ab.clock.Now()) { - if err = cached.flush(batch); err != nil { - log.Warnf("failed to flush entry modified by GC for peer: &v, err: %v", id.Pretty(), err) - } - } - dropOrReschedule(gcKey, cached) - cached.Unlock() - continue - } - - record.Reset() - - // otherwise, fetch it from the store, clean it and flush it. - entryKey := addrBookBase.ChildString(gcKey.Name()) - val, err := gc.ab.ds.Get(context.TODO(), entryKey) - if err != nil { - // captures all errors, including ErrNotFound. - dropInError(gcKey, err, "fetching entry") - continue - } - err = record.Unmarshal(val) - if err != nil { - dropInError(gcKey, err, "unmarshalling entry") - continue - } - if record.clean(gc.ab.clock.Now()) { - err = record.flush(batch) - if err != nil { - log.Warnf("failed to flush entry modified by GC for peer: &v, err: %v", id.Pretty(), err) - } - } - dropOrReschedule(gcKey, record) - } - - if err = batch.Commit(context.TODO()); err != nil { - log.Warnf("failed to commit GC purge batch: %v", err) - } -} - -func (gc *dsAddrBookGc) purgeStore() { - select { - case gc.running <- struct{}{}: - defer func() { <-gc.running }() - default: - // yield if lookahead is running. - return - } - - record := &addrsRecord{AddrBookRecord: &pb.AddrBookRecord{}} // empty record to reuse and avoid allocs. - batch, err := newCyclicBatch(gc.ab.ds, defaultOpsPerCyclicBatch) - if err != nil { - log.Warnf("failed while creating batch to purge GC entries: %v", err) - } - - results, err := gc.ab.ds.Query(context.TODO(), purgeStoreQuery) - if err != nil { - log.Warnf("failed while opening iterator: %v", err) - return - } - defer results.Close() - - // keys: /peers/addrs/ - for result := range results.Next() { - record.Reset() - if err = record.Unmarshal(result.Value); err != nil { - // TODO log - continue - } - - id := record.Id.ID - if !record.clean(gc.ab.clock.Now()) { - continue - } - - if err := record.flush(batch); err != nil { - log.Warnf("failed to flush entry modified by GC for peer: &v, err: %v", id, err) - } - gc.ab.cache.Remove(id) - } - - if err = batch.Commit(context.TODO()); err != nil { - log.Warnf("failed to commit GC purge batch: %v", err) - } -} - -// populateLookahead populates the lookahead window by scanning the entire store and picking entries whose earliest -// expiration falls within the window period. -// -// Those entries are stored in the lookahead region in the store, indexed by the timestamp when they need to be -// visited, to facilitate temporal range scans. -func (gc *dsAddrBookGc) populateLookahead() { - if gc.ab.opts.GCLookaheadInterval == 0 { - return - } - - select { - case gc.running <- struct{}{}: - defer func() { <-gc.running }() - default: - // yield if something's running. - return - } - - until := gc.ab.clock.Now().Add(gc.ab.opts.GCLookaheadInterval).Unix() - - var id peer.ID - record := &addrsRecord{AddrBookRecord: &pb.AddrBookRecord{}} - results, err := gc.ab.ds.Query(context.TODO(), populateLookaheadQuery) - if err != nil { - log.Warnf("failed while querying to populate lookahead GC window: %v", err) - return - } - defer results.Close() - - batch, err := newCyclicBatch(gc.ab.ds, defaultOpsPerCyclicBatch) - if err != nil { - log.Warnf("failed while creating batch to populate lookahead GC window: %v", err) - return - } - - for result := range results.Next() { - idb32 := ds.RawKey(result.Key).Name() - k, err := b32.RawStdEncoding.DecodeString(idb32) - if err != nil { - log.Warnf("failed while decoding peer ID from key: %v, err: %v", result.Key, err) - continue - } - if id, err = peer.IDFromBytes(k); err != nil { - log.Warnf("failed while decoding peer ID from key: %v, err: %v", result.Key, err) - } - - // if the record is in cache, use the cached version. - if e, ok := gc.ab.cache.Peek(id); ok { - cached := e.(*addrsRecord) - cached.RLock() - if len(cached.Addrs) == 0 || cached.Addrs[0].Expiry > until { - cached.RUnlock() - continue - } - gcKey := gcLookaheadBase.ChildString(fmt.Sprintf("%d/%s", cached.Addrs[0].Expiry, idb32)) - if err = batch.Put(context.TODO(), gcKey, []byte{}); err != nil { - log.Warnf("failed while inserting GC entry for peer: %v, err: %v", id.Pretty(), err) - } - cached.RUnlock() - continue - } - - record.Reset() - - val, err := gc.ab.ds.Get(context.TODO(), ds.RawKey(result.Key)) - if err != nil { - log.Warnf("failed which getting record from store for peer: %v, err: %v", id.Pretty(), err) - continue - } - if err := record.Unmarshal(val); err != nil { - log.Warnf("failed while unmarshalling record from store for peer: %v, err: %v", id.Pretty(), err) - continue - } - if len(record.Addrs) > 0 && record.Addrs[0].Expiry <= until { - gcKey := gcLookaheadBase.ChildString(fmt.Sprintf("%d/%s", record.Addrs[0].Expiry, idb32)) - if err = batch.Put(context.TODO(), gcKey, []byte{}); err != nil { - log.Warnf("failed while inserting GC entry for peer: %v, err: %v", id.Pretty(), err) - } - } - } - - if err = batch.Commit(context.TODO()); err != nil { - log.Warnf("failed to commit GC lookahead batch: %v", err) - } - - gc.currWindowEnd = until -} - -// orderByTimestampInKey orders the results by comparing the timestamp in the -// key. A lexiographic sort by itself is wrong since "10" is less than "2", but -// as an int 2 is obviously less than 10. -func orderByTimestampInKey(a, b query.Entry) int { - aKey := ds.RawKey(a.Key) - aInt, err := strconv.ParseInt(aKey.Parent().Name(), 10, 64) - if err != nil { - return -1 - } - bKey := ds.RawKey(b.Key) - bInt, err := strconv.ParseInt(bKey.Parent().Name(), 10, 64) - if err != nil { - return -1 - } - if aInt < bInt { - return -1 - } else if aInt == bInt { - return 0 - } - return 1 -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cache.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cache.go deleted file mode 100644 index d3d43aae1..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cache.go +++ /dev/null @@ -1,40 +0,0 @@ -package pstoreds - -// cache abstracts all methods we access from ARCCache, to enable alternate -// implementations such as a no-op one. -type cache interface { - Get(key interface{}) (value interface{}, ok bool) - Add(key, value interface{}) - Remove(key interface{}) - Contains(key interface{}) bool - Peek(key interface{}) (value interface{}, ok bool) - Keys() []interface{} -} - -// noopCache is a dummy implementation that's used when the cache is disabled. -type noopCache struct { -} - -var _ cache = (*noopCache)(nil) - -func (*noopCache) Get(key interface{}) (value interface{}, ok bool) { - return nil, false -} - -func (*noopCache) Add(key, value interface{}) { -} - -func (*noopCache) Remove(key interface{}) { -} - -func (*noopCache) Contains(key interface{}) bool { - return false -} - -func (*noopCache) Peek(key interface{}) (value interface{}, ok bool) { - return nil, false -} - -func (*noopCache) Keys() (keys []interface{}) { - return keys -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cyclic_batch.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cyclic_batch.go deleted file mode 100644 index 51f6afb0d..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/cyclic_batch.go +++ /dev/null @@ -1,78 +0,0 @@ -package pstoreds - -import ( - "context" - "errors" - "fmt" - - ds "github.com/ipfs/go-datastore" -) - -// how many operations are queued in a cyclic batch before we flush it. -var defaultOpsPerCyclicBatch = 20 - -// cyclicBatch buffers ds write operations and automatically flushes them after defaultOpsPerCyclicBatch (20) have been -// queued. An explicit `Commit()` closes this cyclic batch, erroring all further operations. -// -// It is similar to go-ds autobatch, but it's driven by an actual Batch facility offered by the -// ds. -type cyclicBatch struct { - threshold int - ds.Batch - ds ds.Batching - pending int -} - -func newCyclicBatch(ds ds.Batching, threshold int) (ds.Batch, error) { - batch, err := ds.Batch(context.TODO()) - if err != nil { - return nil, err - } - return &cyclicBatch{Batch: batch, ds: ds}, nil -} - -func (cb *cyclicBatch) cycle() (err error) { - if cb.Batch == nil { - return errors.New("cyclic batch is closed") - } - if cb.pending < cb.threshold { - // we haven't reached the threshold yet. - return nil - } - // commit and renew the batch. - if err = cb.Batch.Commit(context.TODO()); err != nil { - return fmt.Errorf("failed while committing cyclic batch: %w", err) - } - if cb.Batch, err = cb.ds.Batch(context.TODO()); err != nil { - return fmt.Errorf("failed while renewing cyclic batch: %w", err) - } - return nil -} - -func (cb *cyclicBatch) Put(ctx context.Context, key ds.Key, val []byte) error { - if err := cb.cycle(); err != nil { - return err - } - cb.pending++ - return cb.Batch.Put(ctx, key, val) -} - -func (cb *cyclicBatch) Delete(ctx context.Context, key ds.Key) error { - if err := cb.cycle(); err != nil { - return err - } - cb.pending++ - return cb.Batch.Delete(ctx, key) -} - -func (cb *cyclicBatch) Commit(ctx context.Context) error { - if cb.Batch == nil { - return errors.New("cyclic batch is closed") - } - if err := cb.Batch.Commit(ctx); err != nil { - return err - } - cb.pending = 0 - cb.Batch = nil - return nil -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/keybook.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/keybook.go deleted file mode 100644 index 7ee06c81f..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/keybook.go +++ /dev/null @@ -1,137 +0,0 @@ -package pstoreds - -import ( - "context" - "errors" - - "github.com/multiformats/go-base32" - - ds "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/query" - - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" -) - -// Public and private keys are stored under the following db key pattern: -// /peers/keys//{pub, priv} -var ( - kbBase = ds.NewKey("/peers/keys") - pubSuffix = ds.NewKey("/pub") - privSuffix = ds.NewKey("/priv") -) - -type dsKeyBook struct { - ds ds.Datastore -} - -var _ pstore.KeyBook = (*dsKeyBook)(nil) - -func NewKeyBook(_ context.Context, store ds.Datastore, _ Options) (*dsKeyBook, error) { - return &dsKeyBook{store}, nil -} - -func (kb *dsKeyBook) PubKey(p peer.ID) ic.PubKey { - key := peerToKey(p, pubSuffix) - - var pk ic.PubKey - if value, err := kb.ds.Get(context.TODO(), key); err == nil { - pk, err = ic.UnmarshalPublicKey(value) - if err != nil { - log.Errorf("error when unmarshalling pubkey from datastore for peer %s: %s\n", p.Pretty(), err) - } - } else if err == ds.ErrNotFound { - pk, err = p.ExtractPublicKey() - switch err { - case nil: - case peer.ErrNoPublicKey: - return nil - default: - log.Errorf("error when extracting pubkey from peer ID for peer %s: %s\n", p.Pretty(), err) - return nil - } - pkb, err := ic.MarshalPublicKey(pk) - if err != nil { - log.Errorf("error when turning extracted pubkey into bytes for peer %s: %s\n", p.Pretty(), err) - return nil - } - if err := kb.ds.Put(context.TODO(), key, pkb); err != nil { - log.Errorf("error when adding extracted pubkey to peerstore for peer %s: %s\n", p.Pretty(), err) - return nil - } - } else { - log.Errorf("error when fetching pubkey from datastore for peer %s: %s\n", p.Pretty(), err) - } - - return pk -} - -func (kb *dsKeyBook) AddPubKey(p peer.ID, pk ic.PubKey) error { - // check it's correct. - if !p.MatchesPublicKey(pk) { - return errors.New("peer ID does not match public key") - } - - val, err := ic.MarshalPublicKey(pk) - if err != nil { - log.Errorf("error while converting pubkey byte string for peer %s: %s\n", p.Pretty(), err) - return err - } - if err := kb.ds.Put(context.TODO(), peerToKey(p, pubSuffix), val); err != nil { - log.Errorf("error while updating pubkey in datastore for peer %s: %s\n", p.Pretty(), err) - return err - } - return nil -} - -func (kb *dsKeyBook) PrivKey(p peer.ID) ic.PrivKey { - value, err := kb.ds.Get(context.TODO(), peerToKey(p, privSuffix)) - if err != nil { - return nil - } - sk, err := ic.UnmarshalPrivateKey(value) - if err != nil { - return nil - } - return sk -} - -func (kb *dsKeyBook) AddPrivKey(p peer.ID, sk ic.PrivKey) error { - if sk == nil { - return errors.New("private key is nil") - } - // check it's correct. - if !p.MatchesPrivateKey(sk) { - return errors.New("peer ID does not match private key") - } - - val, err := ic.MarshalPrivateKey(sk) - if err != nil { - log.Errorf("error while converting privkey byte string for peer %s: %s\n", p.Pretty(), err) - return err - } - if err := kb.ds.Put(context.TODO(), peerToKey(p, privSuffix), val); err != nil { - log.Errorf("error while updating privkey in datastore for peer %s: %s\n", p.Pretty(), err) - } - return err -} - -func (kb *dsKeyBook) PeersWithKeys() peer.IDSlice { - ids, err := uniquePeerIds(kb.ds, kbBase, func(result query.Result) string { - return ds.RawKey(result.Key).Parent().Name() - }) - if err != nil { - log.Errorf("error while retrieving peers with keys: %v", err) - } - return ids -} - -func (kb *dsKeyBook) RemovePeer(p peer.ID) { - kb.ds.Delete(context.TODO(), peerToKey(p, privSuffix)) - kb.ds.Delete(context.TODO(), peerToKey(p, pubSuffix)) -} - -func peerToKey(p peer.ID, suffix ds.Key) ds.Key { - return kbBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).Child(suffix) -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/metadata.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/metadata.go deleted file mode 100644 index 142017357..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/metadata.go +++ /dev/null @@ -1,81 +0,0 @@ -package pstoreds - -import ( - "bytes" - "context" - "encoding/gob" - - pool "github.com/libp2p/go-buffer-pool" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - - ds "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/query" - "github.com/multiformats/go-base32" -) - -// Metadata is stored under the following db key pattern: -// /peers/metadata// -var pmBase = ds.NewKey("/peers/metadata") - -type dsPeerMetadata struct { - ds ds.Datastore -} - -var _ pstore.PeerMetadata = (*dsPeerMetadata)(nil) - -func init() { - // Gob registers basic types by default. - // - // Register complex types used by the peerstore itself. - gob.Register(make(map[string]struct{})) -} - -// NewPeerMetadata creates a metadata store backed by a persistent db. It uses gob for serialisation. -// -// See `init()` to learn which types are registered by default. Modules wishing to store -// values of other types will need to `gob.Register()` them explicitly, or else callers -// will receive runtime errors. -func NewPeerMetadata(_ context.Context, store ds.Datastore, _ Options) (*dsPeerMetadata, error) { - return &dsPeerMetadata{store}, nil -} - -func (pm *dsPeerMetadata) Get(p peer.ID, key string) (interface{}, error) { - k := pmBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).ChildString(key) - value, err := pm.ds.Get(context.TODO(), k) - if err != nil { - if err == ds.ErrNotFound { - err = pstore.ErrNotFound - } - return nil, err - } - - var res interface{} - if err := gob.NewDecoder(bytes.NewReader(value)).Decode(&res); err != nil { - return nil, err - } - return res, nil -} - -func (pm *dsPeerMetadata) Put(p peer.ID, key string, val interface{}) error { - k := pmBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).ChildString(key) - var buf pool.Buffer - if err := gob.NewEncoder(&buf).Encode(&val); err != nil { - return err - } - return pm.ds.Put(context.TODO(), k, buf.Bytes()) -} - -func (pm *dsPeerMetadata) RemovePeer(p peer.ID) { - result, err := pm.ds.Query(context.TODO(), query.Query{ - Prefix: pmBase.ChildString(base32.RawStdEncoding.EncodeToString([]byte(p))).String(), - KeysOnly: true, - }) - if err != nil { - log.Warnw("querying datastore when removing peer failed", "peer", p, "error", err) - return - } - for entry := range result.Next() { - pm.ds.Delete(context.TODO(), ds.NewKey(entry.Key)) - } -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/peerstore.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/peerstore.go deleted file mode 100644 index 3119be397..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/peerstore.go +++ /dev/null @@ -1,191 +0,0 @@ -package pstoreds - -import ( - "context" - "fmt" - "io" - "time" - - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - pstore "github.com/libp2p/go-libp2p-peerstore" - - ds "github.com/ipfs/go-datastore" - "github.com/ipfs/go-datastore/query" - "github.com/multiformats/go-base32" -) - -// Configuration object for the peerstore. -type Options struct { - // The size of the in-memory cache. A value of 0 or lower disables the cache. - CacheSize uint - - // MaxProtocols is the maximum number of protocols we store for one peer. - MaxProtocols int - - // Sweep interval to purge expired addresses from the datastore. If this is a zero value, GC will not run - // automatically, but it'll be available on demand via explicit calls. - GCPurgeInterval time.Duration - - // Interval to renew the GC lookahead window. If this is a zero value, lookahead will be disabled and we'll - // traverse the entire datastore for every purge cycle. - GCLookaheadInterval time.Duration - - // Initial delay before GC processes start. Intended to give the system breathing room to fully boot - // before starting GC. - GCInitialDelay time.Duration - - Clock clock -} - -// DefaultOpts returns the default options for a persistent peerstore, with the full-purge GC algorithm: -// -// * Cache size: 1024. -// * MaxProtocols: 1024. -// * GC purge interval: 2 hours. -// * GC lookahead interval: disabled. -// * GC initial delay: 60 seconds. -func DefaultOpts() Options { - return Options{ - CacheSize: 1024, - MaxProtocols: 1024, - GCPurgeInterval: 2 * time.Hour, - GCLookaheadInterval: 0, - GCInitialDelay: 60 * time.Second, - Clock: realclock{}, - } -} - -type pstoreds struct { - peerstore.Metrics - - *dsKeyBook - *dsAddrBook - *dsProtoBook - *dsPeerMetadata -} - -var _ peerstore.Peerstore = &pstoreds{} - -// NewPeerstore creates a peerstore backed by the provided persistent datastore. -// It's the caller's responsibility to call RemovePeer to ensure -// that memory consumption of the peerstore doesn't grow unboundedly. -func NewPeerstore(ctx context.Context, store ds.Batching, opts Options) (*pstoreds, error) { - addrBook, err := NewAddrBook(ctx, store, opts) - if err != nil { - return nil, err - } - - keyBook, err := NewKeyBook(ctx, store, opts) - if err != nil { - return nil, err - } - - peerMetadata, err := NewPeerMetadata(ctx, store, opts) - if err != nil { - return nil, err - } - - protoBook, err := NewProtoBook(peerMetadata, WithMaxProtocols(opts.MaxProtocols)) - if err != nil { - return nil, err - } - - return &pstoreds{ - Metrics: pstore.NewMetrics(), - dsKeyBook: keyBook, - dsAddrBook: addrBook, - dsPeerMetadata: peerMetadata, - dsProtoBook: protoBook, - }, nil -} - -// uniquePeerIds extracts and returns unique peer IDs from database keys. -func uniquePeerIds(ds ds.Datastore, prefix ds.Key, extractor func(result query.Result) string) (peer.IDSlice, error) { - var ( - q = query.Query{Prefix: prefix.String(), KeysOnly: true} - results query.Results - err error - ) - - if results, err = ds.Query(context.TODO(), q); err != nil { - log.Error(err) - return nil, err - } - - defer results.Close() - - idset := make(map[string]struct{}) - for result := range results.Next() { - k := extractor(result) - idset[k] = struct{}{} - } - - if len(idset) == 0 { - return peer.IDSlice{}, nil - } - - ids := make(peer.IDSlice, 0, len(idset)) - for id := range idset { - pid, _ := base32.RawStdEncoding.DecodeString(id) - id, _ := peer.IDFromBytes(pid) - ids = append(ids, id) - } - return ids, nil -} - -func (ps *pstoreds) Close() (err error) { - var errs []error - weakClose := func(name string, c interface{}) { - if cl, ok := c.(io.Closer); ok { - if err = cl.Close(); err != nil { - errs = append(errs, fmt.Errorf("%s error: %s", name, err)) - } - } - } - weakClose("keybook", ps.dsKeyBook) - weakClose("addressbook", ps.dsAddrBook) - weakClose("protobook", ps.dsProtoBook) - weakClose("peermetadata", ps.dsPeerMetadata) - - if len(errs) > 0 { - return fmt.Errorf("failed while closing peerstore; err(s): %q", errs) - } - return nil -} - -func (ps *pstoreds) Peers() peer.IDSlice { - set := map[peer.ID]struct{}{} - for _, p := range ps.PeersWithKeys() { - set[p] = struct{}{} - } - for _, p := range ps.PeersWithAddrs() { - set[p] = struct{}{} - } - - pps := make(peer.IDSlice, 0, len(set)) - for p := range set { - pps = append(pps, p) - } - return pps -} - -func (ps *pstoreds) PeerInfo(p peer.ID) peer.AddrInfo { - return peer.AddrInfo{ - ID: p, - Addrs: ps.dsAddrBook.Addrs(p), - } -} - -// RemovePeer removes entries associated with a peer from: -// * the KeyBook -// * the ProtoBook -// * the PeerMetadata -// * the Metrics -// It DOES NOT remove the peer from the AddrBook. -func (ps *pstoreds) RemovePeer(p peer.ID) { - ps.dsKeyBook.RemovePeer(p) - ps.dsProtoBook.RemovePeer(p) - ps.dsPeerMetadata.RemovePeer(p) - ps.Metrics.RemovePeer(p) -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/protobook.go b/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/protobook.go deleted file mode 100644 index af44722c2..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoreds/protobook.go +++ /dev/null @@ -1,196 +0,0 @@ -package pstoreds - -import ( - "errors" - "fmt" - "sync" - - "github.com/libp2p/go-libp2p-core/peer" - - pstore "github.com/libp2p/go-libp2p-core/peerstore" -) - -type protoSegment struct { - sync.RWMutex -} - -type protoSegments [256]*protoSegment - -func (s *protoSegments) get(p peer.ID) *protoSegment { - return s[byte(p[len(p)-1])] -} - -var errTooManyProtocols = errors.New("too many protocols") - -type ProtoBookOption func(*dsProtoBook) error - -func WithMaxProtocols(num int) ProtoBookOption { - return func(pb *dsProtoBook) error { - pb.maxProtos = num - return nil - } -} - -type dsProtoBook struct { - segments protoSegments - meta pstore.PeerMetadata - maxProtos int -} - -var _ pstore.ProtoBook = (*dsProtoBook)(nil) - -func NewProtoBook(meta pstore.PeerMetadata, opts ...ProtoBookOption) (*dsProtoBook, error) { - pb := &dsProtoBook{ - meta: meta, - segments: func() (ret protoSegments) { - for i := range ret { - ret[i] = &protoSegment{} - } - return ret - }(), - maxProtos: 1024, - } - - for _, opt := range opts { - if err := opt(pb); err != nil { - return nil, err - } - } - return pb, nil -} - -func (pb *dsProtoBook) SetProtocols(p peer.ID, protos ...string) error { - if len(protos) > pb.maxProtos { - return errTooManyProtocols - } - - protomap := make(map[string]struct{}, len(protos)) - for _, proto := range protos { - protomap[proto] = struct{}{} - } - - s := pb.segments.get(p) - s.Lock() - defer s.Unlock() - - return pb.meta.Put(p, "protocols", protomap) -} - -func (pb *dsProtoBook) AddProtocols(p peer.ID, protos ...string) error { - s := pb.segments.get(p) - s.Lock() - defer s.Unlock() - - pmap, err := pb.getProtocolMap(p) - if err != nil { - return err - } - if len(pmap)+len(protos) > pb.maxProtos { - return errTooManyProtocols - } - - for _, proto := range protos { - pmap[proto] = struct{}{} - } - - return pb.meta.Put(p, "protocols", pmap) -} - -func (pb *dsProtoBook) GetProtocols(p peer.ID) ([]string, error) { - s := pb.segments.get(p) - s.RLock() - defer s.RUnlock() - - pmap, err := pb.getProtocolMap(p) - if err != nil { - return nil, err - } - - res := make([]string, 0, len(pmap)) - for proto := range pmap { - res = append(res, proto) - } - - return res, nil -} - -func (pb *dsProtoBook) SupportsProtocols(p peer.ID, protos ...string) ([]string, error) { - s := pb.segments.get(p) - s.RLock() - defer s.RUnlock() - - pmap, err := pb.getProtocolMap(p) - if err != nil { - return nil, err - } - - res := make([]string, 0, len(protos)) - for _, proto := range protos { - if _, ok := pmap[proto]; ok { - res = append(res, proto) - } - } - - return res, nil -} - -func (pb *dsProtoBook) FirstSupportedProtocol(p peer.ID, protos ...string) (string, error) { - s := pb.segments.get(p) - s.RLock() - defer s.RUnlock() - - pmap, err := pb.getProtocolMap(p) - if err != nil { - return "", err - } - for _, proto := range protos { - if _, ok := pmap[proto]; ok { - return proto, nil - } - } - - return "", nil -} - -func (pb *dsProtoBook) RemoveProtocols(p peer.ID, protos ...string) error { - s := pb.segments.get(p) - s.Lock() - defer s.Unlock() - - pmap, err := pb.getProtocolMap(p) - if err != nil { - return err - } - - if len(pmap) == 0 { - // nothing to do. - return nil - } - - for _, proto := range protos { - delete(pmap, proto) - } - - return pb.meta.Put(p, "protocols", pmap) -} - -func (pb *dsProtoBook) getProtocolMap(p peer.ID) (map[string]struct{}, error) { - iprotomap, err := pb.meta.Get(p, "protocols") - switch err { - default: - return nil, err - case pstore.ErrNotFound: - return make(map[string]struct{}), nil - case nil: - cast, ok := iprotomap.(map[string]struct{}) - if !ok { - return nil, fmt.Errorf("stored protocol set was not a map") - } - - return cast, nil - } -} - -func (pb *dsProtoBook) RemovePeer(p peer.ID) { - pb.meta.RemovePeer(p) -} diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/version.json b/vendor/github.com/libp2p/go-libp2p-peerstore/version.json deleted file mode 100644 index fce1f6732..000000000 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "version": "v0.7.1" -} diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/backoff.go b/vendor/github.com/libp2p/go-libp2p-pubsub/backoff.go index 1a1b6ecf5..4909e1537 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/backoff.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/backoff.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) const ( diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/blacklist.go b/vendor/github.com/libp2p/go-libp2p-pubsub/blacklist.go index a310e3a46..ecaafe8ce 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/blacklist.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/blacklist.go @@ -4,7 +4,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" "github.com/whyrusleeping/timecache" ) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/comm.go b/vendor/github.com/libp2p/go-libp2p-pubsub/comm.go index a135a60a2..14e8c7736 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/comm.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/comm.go @@ -6,8 +6,8 @@ import ( "io" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p-pubsub/pb" diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/discovery.go b/vendor/github.com/libp2p/go-libp2p-pubsub/discovery.go index c89bacd62..cecc6bc0d 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/discovery.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/discovery.go @@ -5,9 +5,9 @@ import ( "math/rand" "time" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" discimpl "github.com/libp2p/go-libp2p/p2p/discovery/backoff" ) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/floodsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/floodsub.go index 04f6d894f..20f592e2d 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/floodsub.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/floodsub.go @@ -3,9 +3,9 @@ package pubsub import ( "context" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) const ( diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/gossip_tracer.go b/vendor/github.com/libp2p/go-libp2p-pubsub/gossip_tracer.go index a40b707ce..7435cf748 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/gossip_tracer.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/gossip_tracer.go @@ -5,8 +5,8 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // gossipTracer is an internal tracer that tracks IWANT requests in order to penalize diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub.go index caea93f51..713bc6232 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub.go @@ -9,12 +9,12 @@ import ( pb "github.com/libp2p/go-libp2p-pubsub/pb" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/protocol" - "github.com/libp2p/go-libp2p-core/record" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/core/record" ) const ( diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub_feat.go b/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub_feat.go index c3b7e77d4..d5750af3b 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub_feat.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/gossipsub_feat.go @@ -3,7 +3,7 @@ package pubsub import ( "fmt" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/protocol" ) // GossipSubFeatureTest is a feature test function; it takes a feature and a protocol ID and diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/mcache.go b/vendor/github.com/libp2p/go-libp2p-pubsub/mcache.go index 889948eb2..e4e82d902 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/mcache.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/mcache.go @@ -3,7 +3,7 @@ package pubsub import ( "fmt" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // NewMessageCache creates a sliding window cache that remembers messages for as diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/notify.go b/vendor/github.com/libp2p/go-libp2p-pubsub/notify.go index b28cf78ac..a18d8a2af 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/notify.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/notify.go @@ -1,8 +1,8 @@ package pubsub import ( - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/peer_gater.go b/vendor/github.com/libp2p/go-libp2p-pubsub/peer_gater.go index 3da2755f0..4e26bc266 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/peer_gater.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/peer_gater.go @@ -8,10 +8,10 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/pubsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/pubsub.go index e44c7f1c7..7442a3497 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/pubsub.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/pubsub.go @@ -12,12 +12,12 @@ import ( pb "github.com/libp2p/go-libp2p-pubsub/pb" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" logging "github.com/ipfs/go-log" "github.com/whyrusleeping/timecache" @@ -221,7 +221,7 @@ type Message struct { ID string ReceivedFrom peer.ID ValidatorData interface{} - Local bool + Local bool } func (m *Message) GetFrom() peer.ID { diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/randomsub.go b/vendor/github.com/libp2p/go-libp2p-pubsub/randomsub.go index 85e7d7898..f29b923f9 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/randomsub.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/randomsub.go @@ -4,9 +4,9 @@ import ( "context" "math" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) const ( diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/score.go b/vendor/github.com/libp2p/go-libp2p-pubsub/score.go index b762b2b0d..ec6c82137 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/score.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/score.go @@ -7,9 +7,9 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" manet "github.com/multiformats/go-multiaddr/net" ) @@ -143,10 +143,11 @@ type TopicScoreSnapshot struct { // When this option is enabled, the supplied function will be invoked periodically to allow // the application to inspect or dump the scores for connected peers. // The supplied function can have one of two signatures: -// - PeerScoreInspectFn, which takes a map of peer IDs to score. -// - ExtendedPeerScoreInspectFn, which takes a map of peer IDs to -// PeerScoreSnapshots and allows inspection of individual score -// components for debugging peer scoring. +// - PeerScoreInspectFn, which takes a map of peer IDs to score. +// - ExtendedPeerScoreInspectFn, which takes a map of peer IDs to +// PeerScoreSnapshots and allows inspection of individual score +// components for debugging peer scoring. +// // This option must be passed _after_ the WithPeerScore option. func WithPeerScoreInspect(inspect interface{}, period time.Duration) Option { return func(ps *PubSub) error { diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/score_params.go b/vendor/github.com/libp2p/go-libp2p-pubsub/score_params.go index f9b7e29b2..99c9526de 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/score_params.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/score_params.go @@ -6,11 +6,14 @@ import ( "net" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) type PeerScoreThresholds struct { - // GossipThreshold is the score threshold below which gossip propagation is supressed; + // whether it is allowed to just set some params and not all of them. + SkipAtomicValidation bool + + // GossipThreshold is the score threshold below which gossip propagation is suppressed; // should be negative. GossipThreshold float64 @@ -18,8 +21,8 @@ type PeerScoreThresholds struct { // publishing (also applies to fanout and floodsub peers); should be negative and <= GossipThreshold. PublishThreshold float64 - // GraylistThreshold is the score threshold below which message processing is supressed altogether, - // implementing an effective graylist according to peer score; should be negative and <= PublisThreshold. + // GraylistThreshold is the score threshold below which message processing is suppressed altogether, + // implementing an effective gray list according to peer score; should be negative and <= PublishThreshold. GraylistThreshold float64 // AcceptPXThreshold is the score threshold below which PX will be ignored; this should be positive @@ -32,25 +35,38 @@ type PeerScoreThresholds struct { } func (p *PeerScoreThresholds) validate() error { - if p.GossipThreshold > 0 || isInvalidNumber(p.GossipThreshold) { - return fmt.Errorf("invalid gossip threshold; it must be <= 0 and a valid number") + + if !p.SkipAtomicValidation || p.PublishThreshold != 0 || p.GossipThreshold != 0 || p.GraylistThreshold != 0 { + if p.GossipThreshold > 0 || isInvalidNumber(p.GossipThreshold) { + return fmt.Errorf("invalid gossip threshold; it must be <= 0 and a valid number") + } + if p.PublishThreshold > 0 || p.PublishThreshold > p.GossipThreshold || isInvalidNumber(p.PublishThreshold) { + return fmt.Errorf("invalid publish threshold; it must be <= 0 and <= gossip threshold and a valid number") + } + if p.GraylistThreshold > 0 || p.GraylistThreshold > p.PublishThreshold || isInvalidNumber(p.GraylistThreshold) { + return fmt.Errorf("invalid graylist threshold; it must be <= 0 and <= publish threshold and a valid number") + } } - if p.PublishThreshold > 0 || p.PublishThreshold > p.GossipThreshold || isInvalidNumber(p.PublishThreshold) { - return fmt.Errorf("invalid publish threshold; it must be <= 0 and <= gossip threshold and a valid number") + + if !p.SkipAtomicValidation || p.AcceptPXThreshold != 0 { + if p.AcceptPXThreshold < 0 || isInvalidNumber(p.AcceptPXThreshold) { + return fmt.Errorf("invalid accept PX threshold; it must be >= 0 and a valid number") + } } - if p.GraylistThreshold > 0 || p.GraylistThreshold > p.PublishThreshold || isInvalidNumber(p.GraylistThreshold) { - return fmt.Errorf("invalid graylist threshold; it must be <= 0 and <= publish threshold and a valid number") - } - if p.AcceptPXThreshold < 0 || isInvalidNumber(p.AcceptPXThreshold) { - return fmt.Errorf("invalid accept PX threshold; it must be >= 0 and a valid number") - } - if p.OpportunisticGraftThreshold < 0 || isInvalidNumber(p.OpportunisticGraftThreshold) { - return fmt.Errorf("invalid opportunistic grafting threshold; it must be >= 0 and a valid number") + + if !p.SkipAtomicValidation || p.OpportunisticGraftThreshold != 0 { + if p.OpportunisticGraftThreshold < 0 || isInvalidNumber(p.OpportunisticGraftThreshold) { + return fmt.Errorf("invalid opportunistic grafting threshold; it must be >= 0 and a valid number") + } } + return nil } type PeerScoreParams struct { + // whether it is allowed to just set some params and not all of them. + SkipAtomicValidation bool + // Score parameters per topic. Topics map[string]*TopicScoreParams @@ -99,12 +115,15 @@ type PeerScoreParams struct { } type TopicScoreParams struct { + // whether it is allowed to just set some params and not all of them. + SkipAtomicValidation bool + // The weight of the topic. TopicWeight float64 // P1: time in the mesh - // This is the time the peer has ben grafted in the mesh. - // The value of of the parameter is the time/TimeInMeshQuantum, capped by TimeInMeshCap + // This is the time the peer has been grafted in the mesh. + // The value of the parameter is the time/TimeInMeshQuantum, capped by TimeInMeshCap. // The weight of the parameter MUST be positive (or zero to disable). TimeInMeshWeight float64 TimeInMeshQuantum time.Duration @@ -124,7 +143,7 @@ type TopicScoreParams struct { // when validation succeeds. // This window accounts for the minimum time before a hostile mesh peer trying to game the score // could replay back a valid message we just sent them. - // It effectively tracks first and near-first deliveries, ie a message seen from a mesh peer + // It effectively tracks first and near-first deliveries, i.e., a message seen from a mesh peer // before we have forwarded it to them. // The parameter has an associated counter, decaying with MeshMessageDeliveriesDecay. // If the counter exceeds the threshold, its value is 0. @@ -159,41 +178,55 @@ func (p *PeerScoreParams) validate() error { } } - // check that the topic score is 0 or something positive - if p.TopicScoreCap < 0 || isInvalidNumber(p.TopicScoreCap) { - return fmt.Errorf("invalid topic score cap; must be positive (or 0 for no cap) and a valid number") + if !p.SkipAtomicValidation || p.TopicScoreCap != 0 { + // check that the topic score is 0 or something positive + if p.TopicScoreCap < 0 || isInvalidNumber(p.TopicScoreCap) { + return fmt.Errorf("invalid topic score cap; must be positive (or 0 for no cap) and a valid number") + } } // check that we have an app specific score; the weight can be anything (but expected positive) if p.AppSpecificScore == nil { - return fmt.Errorf("missing application specific score function") + if p.SkipAtomicValidation { + p.AppSpecificScore = func(p peer.ID) float64 { + return 0 + } + } else { + return fmt.Errorf("missing application specific score function") + } } - // check the IP colocation factor - if p.IPColocationFactorWeight > 0 || isInvalidNumber(p.IPColocationFactorWeight) { - return fmt.Errorf("invalid IPColocationFactorWeight; must be negative (or 0 to disable) and a valid number") - } - if p.IPColocationFactorWeight != 0 && p.IPColocationFactorThreshold < 1 { - return fmt.Errorf("invalid IPColocationFactorThreshold; must be at least 1") + if !p.SkipAtomicValidation || p.IPColocationFactorWeight != 0 { + // check the IP collocation factor + if p.IPColocationFactorWeight > 0 || isInvalidNumber(p.IPColocationFactorWeight) { + return fmt.Errorf("invalid IPColocationFactorWeight; must be negative (or 0 to disable) and a valid number") + } + if p.IPColocationFactorWeight != 0 && p.IPColocationFactorThreshold < 1 { + return fmt.Errorf("invalid IPColocationFactorThreshold; must be at least 1") + } } // check the behaviour penalty - if p.BehaviourPenaltyWeight > 0 || isInvalidNumber(p.BehaviourPenaltyWeight) { - return fmt.Errorf("invalid BehaviourPenaltyWeight; must be negative (or 0 to disable) and a valid number") - } - if p.BehaviourPenaltyWeight != 0 && (p.BehaviourPenaltyDecay <= 0 || p.BehaviourPenaltyDecay >= 1 || isInvalidNumber(p.BehaviourPenaltyDecay)) { - return fmt.Errorf("invalid BehaviourPenaltyDecay; must be between 0 and 1") - } - if p.BehaviourPenaltyThreshold < 0 || isInvalidNumber(p.BehaviourPenaltyThreshold) { - return fmt.Errorf("invalid BehaviourPenaltyThreshold; must be >= 0 and a valid number") + if !p.SkipAtomicValidation || p.BehaviourPenaltyWeight != 0 || p.BehaviourPenaltyThreshold != 0 { + if p.BehaviourPenaltyWeight > 0 || isInvalidNumber(p.BehaviourPenaltyWeight) { + return fmt.Errorf("invalid BehaviourPenaltyWeight; must be negative (or 0 to disable) and a valid number") + } + if p.BehaviourPenaltyWeight != 0 && (p.BehaviourPenaltyDecay <= 0 || p.BehaviourPenaltyDecay >= 1 || isInvalidNumber(p.BehaviourPenaltyDecay)) { + return fmt.Errorf("invalid BehaviourPenaltyDecay; must be between 0 and 1") + } + if p.BehaviourPenaltyThreshold < 0 || isInvalidNumber(p.BehaviourPenaltyThreshold) { + return fmt.Errorf("invalid BehaviourPenaltyThreshold; must be >= 0 and a valid number") + } } // check the decay parameters - if p.DecayInterval < time.Second { - return fmt.Errorf("invalid DecayInterval; must be at least 1s") - } - if p.DecayToZero <= 0 || p.DecayToZero >= 1 || isInvalidNumber(p.DecayToZero) { - return fmt.Errorf("invalid DecayToZero; must be between 0 and 1") + if !p.SkipAtomicValidation || p.DecayInterval != 0 || p.DecayToZero != 0 { + if p.DecayInterval < time.Second { + return fmt.Errorf("invalid DecayInterval; must be at least 1s") + } + if p.DecayToZero <= 0 || p.DecayToZero >= 1 || isInvalidNumber(p.DecayToZero) { + return fmt.Errorf("invalid DecayToZero; must be between 0 and 1") + } } // no need to check the score retention; a value of 0 means that we don't retain scores @@ -207,6 +240,43 @@ func (p *TopicScoreParams) validate() error { } // check P1 + if err := p.validateTimeInMeshParams(); err != nil { + return err + } + + // check P2 + if err := p.validateMessageDeliveryParams(); err != nil { + return err + } + // check P3 + if err := p.validateMeshMessageDeliveryParams(); err != nil { + return err + } + + // check P3b + if err := p.validateMessageFailurePenaltyParams(); err != nil { + return err + } + + // check P4 + if err := p.validateInvalidMessageDeliveryParams(); err != nil { + return err + } + + return nil +} + +func (p *TopicScoreParams) validateTimeInMeshParams() error { + if p.SkipAtomicValidation { + // in non-atomic mode, parameters at their zero values are dismissed from validation. + if p.TimeInMeshWeight == 0 && p.TimeInMeshQuantum == 0 && p.TimeInMeshCap == 0 { + return nil + } + } + + // either atomic validation mode, or some parameters have been set a value, + // hence, proceed with normal validation of all related parameters in this context. + if p.TimeInMeshQuantum == 0 { return fmt.Errorf("invalid TimeInMeshQuantum; must be non zero") } @@ -220,7 +290,20 @@ func (p *TopicScoreParams) validate() error { return fmt.Errorf("invalid TimeInMeshCap; must be positive and a valid number") } - // check P2 + return nil +} + +func (p *TopicScoreParams) validateMessageDeliveryParams() error { + if p.SkipAtomicValidation { + // in non-atomic mode, parameters at their zero values are dismissed from validation. + if p.FirstMessageDeliveriesWeight == 0 && p.FirstMessageDeliveriesCap == 0 && p.FirstMessageDeliveriesDecay == 0 { + return nil + } + } + + // either atomic validation mode, or some parameters have been set a value, + // hence, proceed with normal validation of all related parameters in this context. + if p.FirstMessageDeliveriesWeight < 0 || isInvalidNumber(p.FirstMessageDeliveriesWeight) { return fmt.Errorf("invallid FirstMessageDeliveriesWeight; must be positive (or 0 to disable) and a valid number") } @@ -231,7 +314,25 @@ func (p *TopicScoreParams) validate() error { return fmt.Errorf("invalid FirstMessageDeliveriesCap; must be positive and a valid number") } - // check P3 + return nil +} + +func (p *TopicScoreParams) validateMeshMessageDeliveryParams() error { + if p.SkipAtomicValidation { + // in non-atomic mode, parameters at their zero values are dismissed from validation. + if p.MeshMessageDeliveriesWeight == 0 && + p.MeshMessageDeliveriesCap == 0 && + p.MeshMessageDeliveriesDecay == 0 && + p.MeshMessageDeliveriesThreshold == 0 && + p.MeshMessageDeliveriesWindow == 0 && + p.MeshMessageDeliveriesActivation == 0 { + return nil + } + } + + // either atomic validation mode, or some parameters have been set a value, + // hence, proceed with normal validation of all related parameters in this context. + if p.MeshMessageDeliveriesWeight > 0 || isInvalidNumber(p.MeshMessageDeliveriesWeight) { return fmt.Errorf("invalid MeshMessageDeliveriesWeight; must be negative (or 0 to disable) and a valid number") } @@ -251,7 +352,20 @@ func (p *TopicScoreParams) validate() error { return fmt.Errorf("invalid MeshMessageDeliveriesActivation; must be at least 1s") } - // check P3b + return nil +} + +func (p *TopicScoreParams) validateMessageFailurePenaltyParams() error { + if p.SkipAtomicValidation { + // in selective mode, parameters at their zero values are dismissed from validation. + if p.MeshFailurePenaltyDecay == 0 && p.MeshFailurePenaltyWeight == 0 { + return nil + } + } + + // either atomic validation mode, or some parameters have been set a value, + // hence, proceed with normal validation of all related parameters in this context. + if p.MeshFailurePenaltyWeight > 0 || isInvalidNumber(p.MeshFailurePenaltyWeight) { return fmt.Errorf("invalid MeshFailurePenaltyWeight; must be negative (or 0 to disable) and a valid number") } @@ -259,7 +373,20 @@ func (p *TopicScoreParams) validate() error { return fmt.Errorf("invalid MeshFailurePenaltyDecay; must be between 0 and 1") } - // check P4 + return nil +} + +func (p *TopicScoreParams) validateInvalidMessageDeliveryParams() error { + if p.SkipAtomicValidation { + // in selective mode, parameters at their zero values are dismissed from validation. + if p.InvalidMessageDeliveriesDecay == 0 && p.InvalidMessageDeliveriesWeight == 0 { + return nil + } + } + + // either atomic validation mode, or some parameters have been set a value, + // hence, proceed with normal validation of all related parameters in this context. + if p.InvalidMessageDeliveriesWeight > 0 || isInvalidNumber(p.InvalidMessageDeliveriesWeight) { return fmt.Errorf("invalid InvalidMessageDeliveriesWeight; must be negative (or 0 to disable) and a valid number") } @@ -281,7 +408,7 @@ func ScoreParameterDecay(decay time.Duration) float64 { return ScoreParameterDecayWithBase(decay, DefaultDecayInterval, DefaultDecayToZero) } -// ScoreParameterDecay computes the decay factor for a parameter using base as the DecayInterval +// ScoreParameterDecayWithBase computes the decay factor for a parameter using base as the DecayInterval func ScoreParameterDecayWithBase(decay time.Duration, base time.Duration, decayToZero float64) float64 { // the decay is linear, so after n ticks the value is factor^n // so factor^n = decayToZero => factor = decayToZero^(1/n) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/sign.go b/vendor/github.com/libp2p/go-libp2p-pubsub/sign.go index e56153a28..3a127c566 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/sign.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/sign.go @@ -5,8 +5,8 @@ import ( pb "github.com/libp2p/go-libp2p-pubsub/pb" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ) // MessageSignaturePolicy describes if signatures are produced, expected, and/or verified. diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/subscription_filter.go b/vendor/github.com/libp2p/go-libp2p-pubsub/subscription_filter.go index 76e6eaa99..8ac65fc43 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/subscription_filter.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/subscription_filter.go @@ -6,7 +6,7 @@ import ( pb "github.com/libp2p/go-libp2p-pubsub/pb" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // ErrTooManySubscriptions may be returned by a SubscriptionFilter to signal that there are too many diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/tag_tracer.go b/vendor/github.com/libp2p/go-libp2p-pubsub/tag_tracer.go index 333edf842..d813c1884 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/tag_tracer.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/tag_tracer.go @@ -5,9 +5,9 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) var ( @@ -34,13 +34,13 @@ var ( // connections based on their behavior. // // We tag a peer's connections for the following reasons: -// - Directly connected peers are tagged with GossipSubConnTagValueDirectPeer (default 1000). -// - Mesh peers are tagged with a value of GossipSubConnTagValueMeshPeer (default 20). -// If a peer is in multiple topic meshes, they'll be tagged for each. -// - For each message that we receive, we bump a delivery tag for peer that delivered the message -// first. -// The delivery tags have a maximum value, GossipSubConnTagMessageDeliveryCap, and they decay at -// a rate of GossipSubConnTagDecayAmount / GossipSubConnTagDecayInterval. +// - Directly connected peers are tagged with GossipSubConnTagValueDirectPeer (default 1000). +// - Mesh peers are tagged with a value of GossipSubConnTagValueMeshPeer (default 20). +// If a peer is in multiple topic meshes, they'll be tagged for each. +// - For each message that we receive, we bump a delivery tag for peer that delivered the message +// first. +// The delivery tags have a maximum value, GossipSubConnTagMessageDeliveryCap, and they decay at +// a rate of GossipSubConnTagDecayAmount / GossipSubConnTagDecayInterval. type tagTracer struct { sync.RWMutex diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/topic.go b/vendor/github.com/libp2p/go-libp2p-pubsub/topic.go index 901edcffd..c08b081b1 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/topic.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/topic.go @@ -7,10 +7,10 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/crypto" pb "github.com/libp2p/go-libp2p-pubsub/pb" + "github.com/libp2p/go-libp2p/core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // ErrTopicClosed is returned if a Topic is utilized after it has been closed @@ -215,7 +215,7 @@ type ProvideKey func() (crypto.PrivKey, peer.ID) type PublishOptions struct { ready RouterReady customKey ProvideKey - local bool + local bool } type PubOpt func(pub *PublishOptions) error diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/trace.go b/vendor/github.com/libp2p/go-libp2p-pubsub/trace.go index 1426e318a..27fac289f 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/trace.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/trace.go @@ -3,8 +3,8 @@ package pubsub import ( "time" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" pb "github.com/libp2p/go-libp2p-pubsub/pb" ) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/tracer.go b/vendor/github.com/libp2p/go-libp2p-pubsub/tracer.go index 0f0b090fa..8e744c911 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/tracer.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/tracer.go @@ -11,11 +11,11 @@ import ( pb "github.com/libp2p/go-libp2p-pubsub/pb" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-msgio/protoio" ) diff --git a/vendor/github.com/libp2p/go-libp2p-pubsub/validation.go b/vendor/github.com/libp2p/go-libp2p-pubsub/validation.go index 9fa28d26c..0c11fc249 100644 --- a/vendor/github.com/libp2p/go-libp2p-pubsub/validation.go +++ b/vendor/github.com/libp2p/go-libp2p-pubsub/validation.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) const ( @@ -478,7 +478,7 @@ func (val *topicVal) validateMsg(ctx context.Context, src peer.ID, msg *Message) } } -/// Options +// / Options // WithValidateQueueSize sets the buffer of validate queue. Defaults to 32. // When queue is full, validation is throttled and new messages are dropped. diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/.gitignore b/vendor/github.com/libp2p/go-libp2p-resource-manager/.gitignore deleted file mode 100644 index 66fd13c90..000000000 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.exe~ -*.dll -*.so -*.dylib - -# Test binary, built with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Dependency directories (remove the comment below to include it) -# vendor/ diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/LICENSE b/vendor/github.com/libp2p/go-libp2p-resource-manager/LICENSE deleted file mode 100644 index a4074ad55..000000000 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 libp2p - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/version.json b/vendor/github.com/libp2p/go-libp2p-resource-manager/version.json deleted file mode 100644 index 4ab5086b7..000000000 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "version": "v0.5.1" -} diff --git a/vendor/github.com/libp2p/go-libp2p/config/config.go b/vendor/github.com/libp2p/go-libp2p/config/config.go index e1ce65456..0634ef4a3 100644 --- a/vendor/github.com/libp2p/go-libp2p/config/config.go +++ b/vendor/github.com/libp2p/go-libp2p/config/config.go @@ -5,23 +5,22 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/metrics" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/pnet" - "github.com/libp2p/go-libp2p-core/routing" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/transport" - "github.com/libp2p/go-libp2p-peerstore/pstoremem" - + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/metrics" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/routing" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/host/autonat" "github.com/libp2p/go-libp2p/p2p/host/autorelay" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" blankhost "github.com/libp2p/go-libp2p/p2p/host/blank" + "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" routed "github.com/libp2p/go-libp2p/p2p/host/routed" "github.com/libp2p/go-libp2p/p2p/net/swarm" tptu "github.com/libp2p/go-libp2p/p2p/net/upgrader" @@ -65,6 +64,11 @@ type Config struct { // Set it via the UserAgent option function. UserAgent string + // ProtocolVersion is the protocol version that identifies the family + // of protocols used by the peer in the Identify protocol. It is set + // using the [ProtocolVersion] option. + ProtocolVersion string + PeerKey crypto.PrivKey Transports []TptC @@ -151,6 +155,9 @@ func (cfg *Config) makeSwarm() (*swarm.Swarm, error) { if cfg.ResourceManager != nil { opts = append(opts, swarm.WithResourceManager(cfg.ResourceManager)) } + if cfg.MultiaddrResolver != nil { + opts = append(opts, swarm.WithMultiaddrResolver(cfg.MultiaddrResolver)) + } // TODO: Make the swarm implementation configurable. return swarm.NewSwarm(pid, cfg.Peerstore, opts...) } @@ -189,7 +196,7 @@ func (cfg *Config) addTransports(h host.Host) error { if err != nil { return err } - tpts, err := makeTransports(h, upgrader, cfg.ConnectionGater, cfg.PSK, cfg.ResourceManager, cfg.Transports) + tpts, err := makeTransports(h, upgrader, cfg.ConnectionGater, cfg.PSK, cfg.ResourceManager, cfg.MultiaddrResolver, cfg.Transports) if err != nil { return err } @@ -224,7 +231,7 @@ func (cfg *Config) NewNode() (host.Host, error) { NATManager: cfg.NATManager, EnablePing: !cfg.DisablePing, UserAgent: cfg.UserAgent, - MultiaddrResolver: cfg.MultiaddrResolver, + ProtocolVersion: cfg.ProtocolVersion, EnableHolePunching: cfg.EnableHolePunching, HolePunchingOptions: cfg.HolePunchingOptions, EnableRelayService: cfg.EnableRelayService, diff --git a/vendor/github.com/libp2p/go-libp2p/config/constructor_types.go b/vendor/github.com/libp2p/go-libp2p/config/constructor_types.go index 631a44cda..53a105ba3 100644 --- a/vendor/github.com/libp2p/go-libp2p/config/constructor_types.go +++ b/vendor/github.com/libp2p/go-libp2p/config/constructor_types.go @@ -4,15 +4,17 @@ import ( "fmt" "reflect" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/pnet" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/transport" + + madns "github.com/multiformats/go-multiaddr-dns" ) var ( @@ -30,41 +32,45 @@ var ( rcmgrType = reflect.TypeOf((*network.ResourceManager)(nil)).Elem() // concrete types - peerIDType = reflect.TypeOf((peer.ID)("")) - pskType = reflect.TypeOf((pnet.PSK)(nil)) + peerIDType = reflect.TypeOf((peer.ID)("")) + pskType = reflect.TypeOf((pnet.PSK)(nil)) + resolverType = reflect.TypeOf((*madns.Resolver)(nil)) ) var argTypes = map[reflect.Type]constructor{ - upgraderType: func(_ host.Host, u transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + upgraderType: func(_ host.Host, u transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return u }, - hostType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + hostType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return h }, - networkType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + networkType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return h.Network() }, - pskType: func(_ host.Host, _ transport.Upgrader, psk pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + pskType: func(_ host.Host, _ transport.Upgrader, psk pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return psk }, - connGaterType: func(_ host.Host, _ transport.Upgrader, _ pnet.PSK, cg connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + connGaterType: func(_ host.Host, _ transport.Upgrader, _ pnet.PSK, cg connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return cg }, - peerIDType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + peerIDType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return h.ID() }, - privKeyType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + privKeyType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return h.Peerstore().PrivKey(h.ID()) }, - pubKeyType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + pubKeyType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return h.Peerstore().PubKey(h.ID()) }, - pstoreType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) interface{} { + pstoreType: func(h host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) interface{} { return h.Peerstore() }, - rcmgrType: func(_ host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, rcmgr network.ResourceManager) interface{} { + rcmgrType: func(_ host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, rcmgr network.ResourceManager, _ *madns.Resolver) interface{} { return rcmgr }, + resolverType: func(_ host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, r *madns.Resolver) interface{} { + return r + }, } func newArgTypeSet(types ...reflect.Type) map[reflect.Type]constructor { diff --git a/vendor/github.com/libp2p/go-libp2p/config/muxer.go b/vendor/github.com/libp2p/go-libp2p/config/muxer.go index 2b3e85708..30a3fa2f7 100644 --- a/vendor/github.com/libp2p/go-libp2p/config/muxer.go +++ b/vendor/github.com/libp2p/go-libp2p/config/muxer.go @@ -3,11 +3,9 @@ package config import ( "fmt" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" msmux "github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream" - - "github.com/libp2p/go-libp2p-core/network" - - "github.com/libp2p/go-libp2p-core/host" ) // MuxC is a stream multiplex transport constructor. @@ -37,7 +35,7 @@ func MuxerConstructor(m interface{}) (MuxC, error) { return nil, err } return func(h host.Host) (network.Multiplexer, error) { - t, err := ctor(h, nil, nil, nil, nil) + t, err := ctor(h, nil, nil, nil, nil, nil) if err != nil { return nil, err } diff --git a/vendor/github.com/libp2p/go-libp2p/config/reflection_magic.go b/vendor/github.com/libp2p/go-libp2p/config/reflection_magic.go index b086f85e4..bb2f52c6b 100644 --- a/vendor/github.com/libp2p/go-libp2p/config/reflection_magic.go +++ b/vendor/github.com/libp2p/go-libp2p/config/reflection_magic.go @@ -6,13 +6,13 @@ import ( "reflect" "runtime" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/transport" - "github.com/libp2p/go-libp2p-core/pnet" - - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/transport" + madns "github.com/multiformats/go-multiaddr-dns" ) var errorType = reflect.TypeOf((*error)(nil)).Elem() @@ -82,7 +82,7 @@ func callConstructor(c reflect.Value, args []reflect.Value) (interface{}, error) return val, err } -type constructor func(host.Host, transport.Upgrader, pnet.PSK, connmgr.ConnectionGater, network.ResourceManager) interface{} +type constructor func(host.Host, transport.Upgrader, pnet.PSK, connmgr.ConnectionGater, network.ResourceManager, *madns.Resolver) interface{} func makeArgumentConstructors(fnType reflect.Type, argTypes map[reflect.Type]constructor) ([]constructor, error) { params := fnType.NumIn() @@ -133,7 +133,7 @@ func makeConstructor( tptType reflect.Type, argTypes map[reflect.Type]constructor, opts ...interface{}, -) (func(host.Host, transport.Upgrader, pnet.PSK, connmgr.ConnectionGater, network.ResourceManager) (interface{}, error), error) { +) (func(host.Host, transport.Upgrader, pnet.PSK, connmgr.ConnectionGater, network.ResourceManager, *madns.Resolver) (interface{}, error), error) { v := reflect.ValueOf(tpt) // avoid panicing on nil/zero value. if v == (reflect.Value{}) { @@ -157,10 +157,10 @@ func makeConstructor( return nil, err } - return func(h host.Host, u transport.Upgrader, psk pnet.PSK, cg connmgr.ConnectionGater, rcmgr network.ResourceManager) (interface{}, error) { + return func(h host.Host, u transport.Upgrader, psk pnet.PSK, cg connmgr.ConnectionGater, rcmgr network.ResourceManager, resolver *madns.Resolver) (interface{}, error) { arguments := make([]reflect.Value, 0, len(argConstructors)+len(opts)) for i, makeArg := range argConstructors { - if arg := makeArg(h, u, psk, cg, rcmgr); arg != nil { + if arg := makeArg(h, u, psk, cg, rcmgr, resolver); arg != nil { arguments = append(arguments, reflect.ValueOf(arg)) } else { // ValueOf an un-typed nil yields a zero reflect diff --git a/vendor/github.com/libp2p/go-libp2p/config/security.go b/vendor/github.com/libp2p/go-libp2p/config/security.go index bac3eb218..330cfaf33 100644 --- a/vendor/github.com/libp2p/go-libp2p/config/security.go +++ b/vendor/github.com/libp2p/go-libp2p/config/security.go @@ -3,13 +3,12 @@ package config import ( "fmt" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/sec/insecure" csms "github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream" - - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/sec/insecure" ) // SecC is a security transport constructor. @@ -42,7 +41,7 @@ func SecurityConstructor(security interface{}) (SecC, error) { return nil, err } return func(h host.Host) (sec.SecureTransport, error) { - t, err := ctor(h, nil, nil, nil, nil) + t, err := ctor(h, nil, nil, nil, nil, nil) if err != nil { return nil, err } diff --git a/vendor/github.com/libp2p/go-libp2p/config/transport.go b/vendor/github.com/libp2p/go-libp2p/config/transport.go index c1a5f4ef9..850357f5a 100644 --- a/vendor/github.com/libp2p/go-libp2p/config/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/config/transport.go @@ -1,17 +1,19 @@ package config import ( - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/pnet" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/transport" + + madns "github.com/multiformats/go-multiaddr-dns" ) // TptC is the type for libp2p transport constructors. You probably won't ever // implement this function interface directly. Instead, pass your transport // constructor to TransportConstructor. -type TptC func(host.Host, transport.Upgrader, pnet.PSK, connmgr.ConnectionGater, network.ResourceManager) (transport.Transport, error) +type TptC func(host.Host, transport.Upgrader, pnet.PSK, connmgr.ConnectionGater, network.ResourceManager, *madns.Resolver) (transport.Transport, error) var transportArgTypes = argTypes @@ -39,7 +41,7 @@ var transportArgTypes = argTypes func TransportConstructor(tpt interface{}, opts ...interface{}) (TptC, error) { // Already constructed? if t, ok := tpt.(transport.Transport); ok { - return func(_ host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager) (transport.Transport, error) { + return func(_ host.Host, _ transport.Upgrader, _ pnet.PSK, _ connmgr.ConnectionGater, _ network.ResourceManager, _ *madns.Resolver) (transport.Transport, error) { return t, nil }, nil } @@ -47,8 +49,8 @@ func TransportConstructor(tpt interface{}, opts ...interface{}) (TptC, error) { if err != nil { return nil, err } - return func(h host.Host, u transport.Upgrader, psk pnet.PSK, cg connmgr.ConnectionGater, rcmgr network.ResourceManager) (transport.Transport, error) { - t, err := ctor(h, u, psk, cg, rcmgr) + return func(h host.Host, u transport.Upgrader, psk pnet.PSK, cg connmgr.ConnectionGater, rcmgr network.ResourceManager, resolver *madns.Resolver) (transport.Transport, error) { + t, err := ctor(h, u, psk, cg, rcmgr, resolver) if err != nil { return nil, err } @@ -56,10 +58,10 @@ func TransportConstructor(tpt interface{}, opts ...interface{}) (TptC, error) { }, nil } -func makeTransports(h host.Host, u transport.Upgrader, cg connmgr.ConnectionGater, psk pnet.PSK, rcmgr network.ResourceManager, tpts []TptC) ([]transport.Transport, error) { +func makeTransports(h host.Host, u transport.Upgrader, cg connmgr.ConnectionGater, psk pnet.PSK, rcmgr network.ResourceManager, resolver *madns.Resolver, tpts []TptC) ([]transport.Transport, error) { transports := make([]transport.Transport, len(tpts)) for i, tC := range tpts { - t, err := tC(h, u, psk, cg, rcmgr) + t, err := tC(h, u, psk, cg, rcmgr, resolver) if err != nil { return nil, err } diff --git a/vendor/github.com/libp2p/go-libp2p-core/canonicallog/canonicallog.go b/vendor/github.com/libp2p/go-libp2p/core/canonicallog/canonicallog.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-core/canonicallog/canonicallog.go rename to vendor/github.com/libp2p/go-libp2p/core/canonicallog/canonicallog.go index 2bc07b1e6..3e021ef28 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/canonicallog/canonicallog.go +++ b/vendor/github.com/libp2p/go-libp2p/core/canonicallog/canonicallog.go @@ -6,8 +6,9 @@ import ( "net" "strings" + "github.com/libp2p/go-libp2p/core/peer" + logging "github.com/ipfs/go-log/v2" - "github.com/libp2p/go-libp2p-core/peer" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/connmgr/decay.go b/vendor/github.com/libp2p/go-libp2p/core/connmgr/decay.go similarity index 92% rename from vendor/github.com/libp2p/go-libp2p-core/connmgr/decay.go rename to vendor/github.com/libp2p/go-libp2p/core/connmgr/decay.go index 2ff135a87..783a06c3a 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/connmgr/decay.go +++ b/vendor/github.com/libp2p/go-libp2p/core/connmgr/decay.go @@ -4,7 +4,7 @@ import ( "io" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // Decayer is implemented by connection managers supporting decaying tags. A @@ -22,10 +22,10 @@ import ( // Such a pluggable design affords a great deal of flexibility and versatility. // Behaviours that are straightforward to implement include: // -// * Decay a tag by -1, or by half its current value, on every tick. -// * Every time a value is bumped, sum it to its current value. -// * Exponentially boost a score with every bump. -// * Sum the incoming score, but keep it within min, max bounds. +// - Decay a tag by -1, or by half its current value, on every tick. +// - Every time a value is bumped, sum it to its current value. +// - Exponentially boost a score with every bump. +// - Sum the incoming score, but keep it within min, max bounds. // // Commonly used DecayFns and BumpFns are provided in this package. type Decayer interface { diff --git a/vendor/github.com/libp2p/go-libp2p-core/connmgr/gater.go b/vendor/github.com/libp2p/go-libp2p/core/connmgr/gater.go similarity index 72% rename from vendor/github.com/libp2p/go-libp2p-core/connmgr/gater.go rename to vendor/github.com/libp2p/go-libp2p/core/connmgr/gater.go index 5fc03c92c..672aef952 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/connmgr/gater.go +++ b/vendor/github.com/libp2p/go-libp2p/core/connmgr/gater.go @@ -3,9 +3,9 @@ package connmgr import ( ma "github.com/multiformats/go-multiaddr" - "github.com/libp2p/go-libp2p-core/control" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/control" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // ConnectionGater can be implemented by a type that supports active @@ -17,25 +17,25 @@ import ( // of a connection being established/upgraded. Specific functions will be called // throughout the process, to allow you to intercept the connection at that stage. // -// InterceptPeerDial is called on an imminent outbound peer dial request, prior -// to the addresses of that peer being available/resolved. Blocking connections -// at this stage is typical for blacklisting scenarios. +// InterceptPeerDial is called on an imminent outbound peer dial request, prior +// to the addresses of that peer being available/resolved. Blocking connections +// at this stage is typical for blacklisting scenarios. // -// InterceptAddrDial is called on an imminent outbound dial to a peer on a -// particular address. Blocking connections at this stage is typical for -// address filtering. +// InterceptAddrDial is called on an imminent outbound dial to a peer on a +// particular address. Blocking connections at this stage is typical for +// address filtering. // -// InterceptAccept is called as soon as a transport listener receives an -// inbound connection request, before any upgrade takes place. Transports who -// accept already secure and/or multiplexed connections (e.g. possibly QUIC) -// MUST call this method regardless, for correctness/consistency. +// InterceptAccept is called as soon as a transport listener receives an +// inbound connection request, before any upgrade takes place. Transports who +// accept already secure and/or multiplexed connections (e.g. possibly QUIC) +// MUST call this method regardless, for correctness/consistency. // -// InterceptSecured is called for both inbound and outbound connections, -// after a security handshake has taken place and we've authenticated the peer. +// InterceptSecured is called for both inbound and outbound connections, +// after a security handshake has taken place and we've authenticated the peer. // -// InterceptUpgraded is called for inbound and outbound connections, after -// libp2p has finished upgrading the connection entirely to a secure, -// multiplexed channel. +// InterceptUpgraded is called for inbound and outbound connections, after +// libp2p has finished upgrading the connection entirely to a secure, +// multiplexed channel. // // This interface can be used to implement *strict/active* connection management // policies, such as hard limiting of connections once a maximum count has been diff --git a/vendor/github.com/libp2p/go-libp2p-core/connmgr/manager.go b/vendor/github.com/libp2p/go-libp2p/core/connmgr/manager.go similarity index 97% rename from vendor/github.com/libp2p/go-libp2p-core/connmgr/manager.go rename to vendor/github.com/libp2p/go-libp2p/core/connmgr/manager.go index 223dcdf55..e0d6c5201 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/connmgr/manager.go +++ b/vendor/github.com/libp2p/go-libp2p/core/connmgr/manager.go @@ -10,8 +10,8 @@ import ( "context" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // SupportsDecay evaluates if the provided ConnManager supports decay, and if diff --git a/vendor/github.com/libp2p/go-libp2p-core/connmgr/null.go b/vendor/github.com/libp2p/go-libp2p/core/connmgr/null.go similarity index 91% rename from vendor/github.com/libp2p/go-libp2p-core/connmgr/null.go rename to vendor/github.com/libp2p/go-libp2p/core/connmgr/null.go index 6e00b0878..25743f4ec 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/connmgr/null.go +++ b/vendor/github.com/libp2p/go-libp2p/core/connmgr/null.go @@ -3,8 +3,8 @@ package connmgr import ( "context" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // NullConnMgr is a ConnMgr that provides no functionality. diff --git a/vendor/github.com/libp2p/go-libp2p-core/connmgr/presets.go b/vendor/github.com/libp2p/go-libp2p/core/connmgr/presets.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/connmgr/presets.go rename to vendor/github.com/libp2p/go-libp2p/core/connmgr/presets.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/control/disconnect.go b/vendor/github.com/libp2p/go-libp2p/core/control/disconnect.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/control/disconnect.go rename to vendor/github.com/libp2p/go-libp2p/core/control/disconnect.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/ecdsa.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/ecdsa.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/ecdsa.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/ecdsa.go index 5b8244734..318dcac2b 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/ecdsa.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/ecdsa.go @@ -10,8 +10,8 @@ import ( "io" "math/big" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" - "github.com/libp2p/go-libp2p-core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" + "github.com/libp2p/go-libp2p/core/internal/catch" "github.com/minio/sha256-simd" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/ed25519.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/ed25519.go similarity index 97% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/ed25519.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/ed25519.go index 90713c23a..7cd72efbc 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/ed25519.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/ed25519.go @@ -8,8 +8,8 @@ import ( "fmt" "io" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" - "github.com/libp2p/go-libp2p-core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" + "github.com/libp2p/go-libp2p/core/internal/catch" ) // Ed25519PrivateKey is an ed25519 private key. diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/key.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/key.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/key.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/key.go index 1b7ac8bae..3d7b39a22 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/key.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/key.go @@ -12,7 +12,7 @@ import ( "fmt" "io" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" "github.com/gogo/protobuf/proto" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/key_not_openssl.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/key_not_openssl.go similarity index 86% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/key_not_openssl.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/key_not_openssl.go index 28792f8f5..003246752 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/key_not_openssl.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/key_not_openssl.go @@ -9,10 +9,10 @@ import ( "crypto/ed25519" "crypto/rsa" - btcec "github.com/btcsuite/btcd/btcec/v2" + "github.com/decred/dcrd/dcrec/secp256k1/v4" ) -// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p-core/crypto keys +// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p/core/crypto keys func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) { if priv == nil { return nil, nil, ErrNilPrivateKey @@ -30,7 +30,7 @@ func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) { pub, _ := pubIfc.(ed25519.PublicKey) return &Ed25519PrivateKey{*p}, &Ed25519PublicKey{pub}, nil - case *btcec.PrivateKey: + case *secp256k1.PrivateKey: sPriv := Secp256k1PrivateKey(*p) sPub := Secp256k1PublicKey(*p.PubKey()) return &sPriv, &sPub, nil @@ -40,7 +40,7 @@ func KeyPairFromStdKey(priv crypto.PrivateKey) (PrivKey, PubKey, error) { } } -// PrivKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) private keys +// PrivKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) private keys func PrivKeyToStdKey(priv PrivKey) (crypto.PrivateKey, error) { if priv == nil { return nil, ErrNilPrivateKey @@ -60,7 +60,7 @@ func PrivKeyToStdKey(priv PrivKey) (crypto.PrivateKey, error) { } } -// PubKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) public keys +// PubKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) public keys func PubKeyToStdKey(pub PubKey) (crypto.PublicKey, error) { if pub == nil { return nil, ErrNilPublicKey diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/key_openssl.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/key_openssl.go similarity index 87% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/key_openssl.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/key_openssl.go index 60f9ced27..7a13ff69a 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/key_openssl.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/key_openssl.go @@ -10,13 +10,13 @@ import ( "crypto/rsa" "crypto/x509" - btcec "github.com/btcsuite/btcd/btcec/v2" - openssl "github.com/libp2p/go-openssl" + "github.com/libp2p/go-libp2p/core/internal/catch" - "github.com/libp2p/go-libp2p-core/internal/catch" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/libp2p/go-openssl" ) -// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p-core/crypto keys +// KeyPairFromStdKey wraps standard library (and secp256k1) private keys in libp2p/go-libp2p/core/crypto keys func KeyPairFromStdKey(priv crypto.PrivateKey) (_priv PrivKey, _pub PubKey, err error) { if priv == nil { return nil, nil, ErrNilPrivateKey @@ -40,7 +40,7 @@ func KeyPairFromStdKey(priv crypto.PrivateKey) (_priv PrivKey, _pub PubKey, err pub, _ := pubIfc.(ed25519.PublicKey) return &Ed25519PrivateKey{*p}, &Ed25519PublicKey{pub}, nil - case *btcec.PrivateKey: + case *secp256k1.PrivateKey: sPriv := Secp256k1PrivateKey(*p) sPub := Secp256k1PublicKey(*p.PubKey()) return &sPriv, &sPub, nil @@ -50,7 +50,7 @@ func KeyPairFromStdKey(priv crypto.PrivateKey) (_priv PrivKey, _pub PubKey, err } } -// PrivKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) private keys +// PrivKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) private keys func PrivKeyToStdKey(priv PrivKey) (_priv crypto.PrivateKey, err error) { if priv == nil { return nil, ErrNilPrivateKey @@ -74,7 +74,7 @@ func PrivKeyToStdKey(priv PrivKey) (_priv crypto.PrivateKey, err error) { } } -// PubKeyToStdKey converts libp2p/go-libp2p-core/crypto private keys to standard library (and secp256k1) public keys +// PubKeyToStdKey converts libp2p/go-libp2p/core/crypto private keys to standard library (and secp256k1) public keys func PubKeyToStdKey(pub PubKey) (key crypto.PublicKey, err error) { if pub == nil { return nil, ErrNilPublicKey diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/openssl_common.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/openssl_common.go similarity index 97% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/openssl_common.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/openssl_common.go index 257bfada7..d97eb08b8 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/openssl_common.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/openssl_common.go @@ -6,7 +6,7 @@ package crypto import ( "sync" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" "github.com/libp2p/go-openssl" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/Makefile b/vendor/github.com/libp2p/go-libp2p/core/crypto/pb/Makefile similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/pb/Makefile rename to vendor/github.com/libp2p/go-libp2p/core/crypto/pb/Makefile diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.pb.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.pb.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.pb.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.pb.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto b/vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.proto similarity index 80% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto rename to vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.proto index 182b0d484..44e504423 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/pb/crypto.proto @@ -2,7 +2,7 @@ syntax = "proto2"; package crypto.pb; -option go_package = "github.com/libp2p/go-libp2p-core/crypto/pb"; +option go_package = "github.com/libp2p/go-libp2p/core/crypto/pb"; enum KeyType { RSA = 0; diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_common.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_common.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_common.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_common.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_go.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_go.go similarity index 97% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_go.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_go.go index b0df60d98..1324447d2 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_go.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_go.go @@ -11,8 +11,8 @@ import ( "errors" "io" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" - "github.com/libp2p/go-libp2p-core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" + "github.com/libp2p/go-libp2p/core/internal/catch" "github.com/minio/sha256-simd" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_openssl.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_openssl.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/rsa_openssl.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/rsa_openssl.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/crypto/secp256k1.go b/vendor/github.com/libp2p/go-libp2p/core/crypto/secp256k1.go similarity index 74% rename from vendor/github.com/libp2p/go-libp2p-core/crypto/secp256k1.go rename to vendor/github.com/libp2p/go-libp2p/core/crypto/secp256k1.go index d90b23243..3b3aa6fe7 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/crypto/secp256k1.go +++ b/vendor/github.com/libp2p/go-libp2p/core/crypto/secp256k1.go @@ -4,23 +4,23 @@ import ( "fmt" "io" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" - "github.com/libp2p/go-libp2p-core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" + "github.com/libp2p/go-libp2p/core/internal/catch" - btcec "github.com/btcsuite/btcd/btcec/v2" - btcececdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa" + "github.com/decred/dcrd/dcrec/secp256k1/v4" + "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" "github.com/minio/sha256-simd" ) // Secp256k1PrivateKey is an Secp256k1 private key -type Secp256k1PrivateKey btcec.PrivateKey +type Secp256k1PrivateKey secp256k1.PrivateKey // Secp256k1PublicKey is an Secp256k1 public key -type Secp256k1PublicKey btcec.PublicKey +type Secp256k1PublicKey secp256k1.PublicKey // GenerateSecp256k1Key generates a new Secp256k1 private and public key pair func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) { - privk, err := btcec.NewPrivateKey() + privk, err := secp256k1.GeneratePrivateKey() if err != nil { return nil, nil, err } @@ -31,19 +31,19 @@ func GenerateSecp256k1Key(src io.Reader) (PrivKey, PubKey, error) { // UnmarshalSecp256k1PrivateKey returns a private key from bytes func UnmarshalSecp256k1PrivateKey(data []byte) (k PrivKey, err error) { - if len(data) != btcec.PrivKeyBytesLen { - return nil, fmt.Errorf("expected secp256k1 data size to be %d", btcec.PrivKeyBytesLen) + if len(data) != secp256k1.PrivKeyBytesLen { + return nil, fmt.Errorf("expected secp256k1 data size to be %d", secp256k1.PrivKeyBytesLen) } defer func() { catch.HandlePanic(recover(), &err, "secp256k1 private-key unmarshal") }() - privk, _ := btcec.PrivKeyFromBytes(data) + privk := secp256k1.PrivKeyFromBytes(data) return (*Secp256k1PrivateKey)(privk), nil } // UnmarshalSecp256k1PublicKey returns a public key from bytes func UnmarshalSecp256k1PublicKey(data []byte) (_k PubKey, err error) { defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public-key unmarshal") }() - k, err := btcec.ParsePubKey(data) + k, err := secp256k1.ParsePubKey(data) if err != nil { return nil, err } @@ -58,7 +58,7 @@ func (k *Secp256k1PrivateKey) Type() pb.KeyType { // Raw returns the bytes of the key func (k *Secp256k1PrivateKey) Raw() ([]byte, error) { - return (*btcec.PrivateKey)(k).Serialize(), nil + return (*secp256k1.PrivateKey)(k).Serialize(), nil } // Equals compares two private keys @@ -74,16 +74,16 @@ func (k *Secp256k1PrivateKey) Equals(o Key) bool { // Sign returns a signature from input data func (k *Secp256k1PrivateKey) Sign(data []byte) (_sig []byte, err error) { defer func() { catch.HandlePanic(recover(), &err, "secp256k1 signing") }() - key := (*btcec.PrivateKey)(k) + key := (*secp256k1.PrivateKey)(k) hash := sha256.Sum256(data) - sig := btcececdsa.Sign(key, hash[:]) + sig := ecdsa.Sign(key, hash[:]) return sig.Serialize(), nil } // GetPublic returns a public key func (k *Secp256k1PrivateKey) GetPublic() PubKey { - return (*Secp256k1PublicKey)((*btcec.PrivateKey)(k).PubKey()) + return (*Secp256k1PublicKey)((*secp256k1.PrivateKey)(k).PubKey()) } // Type returns the public key type @@ -94,7 +94,7 @@ func (k *Secp256k1PublicKey) Type() pb.KeyType { // Raw returns the bytes of the key func (k *Secp256k1PublicKey) Raw() (res []byte, err error) { defer func() { catch.HandlePanic(recover(), &err, "secp256k1 public key marshaling") }() - return (*btcec.PublicKey)(k).SerializeCompressed(), nil + return (*secp256k1.PublicKey)(k).SerializeCompressed(), nil } // Equals compares two public keys @@ -104,7 +104,7 @@ func (k *Secp256k1PublicKey) Equals(o Key) bool { return basicEquals(k, o) } - return (*btcec.PublicKey)(k).IsEqual((*btcec.PublicKey)(sk)) + return (*secp256k1.PublicKey)(k).IsEqual((*secp256k1.PublicKey)(sk)) } // Verify compares a signature against the input data @@ -117,11 +117,11 @@ func (k *Secp256k1PublicKey) Verify(data []byte, sigStr []byte) (success bool, e success = false } }() - sig, err := btcececdsa.ParseDERSignature(sigStr) + sig, err := ecdsa.ParseDERSignature(sigStr) if err != nil { return false, err } hash := sha256.Sum256(data) - return sig.Verify(hash[:], (*btcec.PublicKey)(k)), nil + return sig.Verify(hash[:], (*secp256k1.PublicKey)(k)), nil } diff --git a/vendor/github.com/libp2p/go-libp2p-core/discovery/discovery.go b/vendor/github.com/libp2p/go-libp2p/core/discovery/discovery.go similarity index 94% rename from vendor/github.com/libp2p/go-libp2p-core/discovery/discovery.go rename to vendor/github.com/libp2p/go-libp2p/core/discovery/discovery.go index f463e0e85..feeb2c797 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/discovery/discovery.go +++ b/vendor/github.com/libp2p/go-libp2p/core/discovery/discovery.go @@ -5,7 +5,7 @@ import ( "context" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // Advertiser is an interface for advertising services diff --git a/vendor/github.com/libp2p/go-libp2p-core/discovery/options.go b/vendor/github.com/libp2p/go-libp2p/core/discovery/options.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/discovery/options.go rename to vendor/github.com/libp2p/go-libp2p/core/discovery/options.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/addrs.go b/vendor/github.com/libp2p/go-libp2p/core/event/addrs.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-core/event/addrs.go rename to vendor/github.com/libp2p/go-libp2p/core/event/addrs.go index 9419d2195..67026d178 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/event/addrs.go +++ b/vendor/github.com/libp2p/go-libp2p/core/event/addrs.go @@ -1,7 +1,8 @@ package event import ( - "github.com/libp2p/go-libp2p-core/record" + "github.com/libp2p/go-libp2p/core/record" + ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/bus.go b/vendor/github.com/libp2p/go-libp2p/core/event/bus.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/event/bus.go rename to vendor/github.com/libp2p/go-libp2p/core/event/bus.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/dht.go b/vendor/github.com/libp2p/go-libp2p/core/event/dht.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/event/dht.go rename to vendor/github.com/libp2p/go-libp2p/core/event/dht.go diff --git a/vendor/github.com/libp2p/go-libp2p/core/event/doc.go b/vendor/github.com/libp2p/go-libp2p/core/event/doc.go new file mode 100644 index 000000000..7ba4bd6f4 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/core/event/doc.go @@ -0,0 +1,11 @@ +// Package event contains the abstractions for a local event bus, along with the standard events +// that libp2p subsystems may emit. +// +// Source code is arranged as follows: +// - doc.go: this file. +// - bus.go: abstractions for the event bus. +// - rest: event structs, sensibly categorised in files by entity, and following this naming convention: +// Evt[Entity (noun)][Event (verb past tense / gerund)] +// The past tense is used to convey that something happened, whereas the gerund form of the verb (-ing) +// expresses that a process is in progress. Examples: EvtConnEstablishing, EvtConnEstablished. +package event diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/identify.go b/vendor/github.com/libp2p/go-libp2p/core/event/identify.go similarity index 91% rename from vendor/github.com/libp2p/go-libp2p-core/event/identify.go rename to vendor/github.com/libp2p/go-libp2p/core/event/identify.go index 7c4d1895f..ff1499587 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/event/identify.go +++ b/vendor/github.com/libp2p/go-libp2p/core/event/identify.go @@ -1,6 +1,6 @@ package event -import "github.com/libp2p/go-libp2p-core/peer" +import "github.com/libp2p/go-libp2p/core/peer" // EvtPeerIdentificationCompleted is emitted when the initial identification round for a peer is completed. type EvtPeerIdentificationCompleted struct { diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/nattype.go b/vendor/github.com/libp2p/go-libp2p/core/event/nattype.go similarity index 95% rename from vendor/github.com/libp2p/go-libp2p-core/event/nattype.go rename to vendor/github.com/libp2p/go-libp2p/core/event/nattype.go index a24eb1a15..21ecdebd5 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/event/nattype.go +++ b/vendor/github.com/libp2p/go-libp2p/core/event/nattype.go @@ -1,6 +1,6 @@ package event -import "github.com/libp2p/go-libp2p-core/network" +import "github.com/libp2p/go-libp2p/core/network" // EvtNATDeviceTypeChanged is an event struct to be emitted when the type of the NAT device changes for a Transport Protocol. // diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/network.go b/vendor/github.com/libp2p/go-libp2p/core/event/network.go similarity index 60% rename from vendor/github.com/libp2p/go-libp2p-core/event/network.go rename to vendor/github.com/libp2p/go-libp2p/core/event/network.go index 15f9f6c89..37e9177d2 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/event/network.go +++ b/vendor/github.com/libp2p/go-libp2p/core/event/network.go @@ -1,48 +1,48 @@ package event import ( - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // EvtPeerConnectednessChanged should be emitted every time the "connectedness" to a // given peer changes. Specifically, this event is emitted in the following // cases: // -// * Connectedness = Connected: Every time we transition from having no -// connections to a peer to having at least one connection to the peer. -// * Connectedness = NotConnected: Every time we transition from having at least -// one connection to a peer to having no connections to the peer. +// - Connectedness = Connected: Every time we transition from having no +// connections to a peer to having at least one connection to the peer. +// - Connectedness = NotConnected: Every time we transition from having at least +// one connection to a peer to having no connections to the peer. // // Additional connectedness states may be added in the future. This list should // not be considered exhaustive. // // Take note: // -// * It's possible to have _multiple_ connections to a given peer. -// * Both libp2p and networks are asynchronous. +// - It's possible to have _multiple_ connections to a given peer. +// - Both libp2p and networks are asynchronous. // // This means that all of the following situations are possible: // // A connection is cut and is re-established: // -// * Peer A observes a transition from Connected -> NotConnected -> Connected -// * Peer B observes a transition from Connected -> NotConnected -> Connected +// - Peer A observes a transition from Connected -> NotConnected -> Connected +// - Peer B observes a transition from Connected -> NotConnected -> Connected // // Explanation: Both peers observe the connection die. This is the "nice" case. // // A connection is cut and is re-established. // -// * Peer A observes a transition from Connected -> NotConnected -> Connected. -// * Peer B observes no transition. +// - Peer A observes a transition from Connected -> NotConnected -> Connected. +// - Peer B observes no transition. // // Explanation: Peer A re-establishes the dead connection. Peer B observes the // new connection form before it observes the old connection die. // // A connection is cut: // -// * Peer A observes no transition. -// * Peer B observes no transition. +// - Peer A observes no transition. +// - Peer B observes no transition. // // Explanation: There were two connections and one was cut. This connection // might have been in active use but neither peer will observe a change in diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/protocol.go b/vendor/github.com/libp2p/go-libp2p/core/event/protocol.go similarity index 89% rename from vendor/github.com/libp2p/go-libp2p-core/event/protocol.go rename to vendor/github.com/libp2p/go-libp2p/core/event/protocol.go index 87b4312da..b8f1fe637 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/event/protocol.go +++ b/vendor/github.com/libp2p/go-libp2p/core/event/protocol.go @@ -1,8 +1,8 @@ package event import ( - peer "github.com/libp2p/go-libp2p-core/peer" - protocol "github.com/libp2p/go-libp2p-core/protocol" + peer "github.com/libp2p/go-libp2p/core/peer" + protocol "github.com/libp2p/go-libp2p/core/protocol" ) // EvtPeerProtocolsUpdated should be emitted when a peer we're connected to adds or removes protocols from their stack. diff --git a/vendor/github.com/libp2p/go-libp2p-core/event/reachability.go b/vendor/github.com/libp2p/go-libp2p/core/event/reachability.go similarity index 86% rename from vendor/github.com/libp2p/go-libp2p-core/event/reachability.go rename to vendor/github.com/libp2p/go-libp2p/core/event/reachability.go index 6bd7db49c..6ab452385 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/event/reachability.go +++ b/vendor/github.com/libp2p/go-libp2p/core/event/reachability.go @@ -1,7 +1,7 @@ package event import ( - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) // EvtLocalReachabilityChanged is an event struct to be emitted when the local's diff --git a/vendor/github.com/libp2p/go-libp2p-core/host/helpers.go b/vendor/github.com/libp2p/go-libp2p/core/host/helpers.go similarity index 81% rename from vendor/github.com/libp2p/go-libp2p-core/host/helpers.go rename to vendor/github.com/libp2p/go-libp2p/core/host/helpers.go index a24beb1bb..e57f326a7 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/host/helpers.go +++ b/vendor/github.com/libp2p/go-libp2p/core/host/helpers.go @@ -1,6 +1,6 @@ package host -import "github.com/libp2p/go-libp2p-core/peer" +import "github.com/libp2p/go-libp2p/core/peer" // InfoFromHost returns a peer.AddrInfo struct with the Host's ID and all of its Addrs. func InfoFromHost(h Host) *peer.AddrInfo { diff --git a/vendor/github.com/libp2p/go-libp2p-core/host/host.go b/vendor/github.com/libp2p/go-libp2p/core/host/host.go similarity index 90% rename from vendor/github.com/libp2p/go-libp2p-core/host/host.go rename to vendor/github.com/libp2p/go-libp2p/core/host/host.go index 8712e68b9..cfea91e5b 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/host/host.go +++ b/vendor/github.com/libp2p/go-libp2p/core/host/host.go @@ -6,13 +6,13 @@ package host import ( "context" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/introspection" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/introspection" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/internal/catch/catch.go b/vendor/github.com/libp2p/go-libp2p/core/internal/catch/catch.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/internal/catch/catch.go rename to vendor/github.com/libp2p/go-libp2p/core/internal/catch/catch.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/introspection/doc.go b/vendor/github.com/libp2p/go-libp2p/core/introspection/doc.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/introspection/doc.go rename to vendor/github.com/libp2p/go-libp2p/core/introspection/doc.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/introspection/endpoint.go b/vendor/github.com/libp2p/go-libp2p/core/introspection/endpoint.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/introspection/endpoint.go rename to vendor/github.com/libp2p/go-libp2p/core/introspection/endpoint.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/introspection/introspector.go b/vendor/github.com/libp2p/go-libp2p/core/introspection/introspector.go similarity index 95% rename from vendor/github.com/libp2p/go-libp2p-core/introspection/introspector.go rename to vendor/github.com/libp2p/go-libp2p/core/introspection/introspector.go index d3bd583f2..e39f9673b 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/introspection/introspector.go +++ b/vendor/github.com/libp2p/go-libp2p/core/introspection/introspector.go @@ -3,7 +3,7 @@ package introspection import ( "io" - "github.com/libp2p/go-libp2p-core/introspection/pb" + "github.com/libp2p/go-libp2p/core/introspection/pb" ) // Introspector is the interface to be satisfied by components that are capable diff --git a/vendor/github.com/libp2p/go-libp2p-core/introspection/pb/Makefile b/vendor/github.com/libp2p/go-libp2p/core/introspection/pb/Makefile similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/introspection/pb/Makefile rename to vendor/github.com/libp2p/go-libp2p/core/introspection/pb/Makefile diff --git a/vendor/github.com/libp2p/go-libp2p-core/introspection/pb/doc.go b/vendor/github.com/libp2p/go-libp2p/core/introspection/pb/doc.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/introspection/pb/doc.go rename to vendor/github.com/libp2p/go-libp2p/core/introspection/pb/doc.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/introspection/pb/introspection.pb.go b/vendor/github.com/libp2p/go-libp2p/core/introspection/pb/introspection.pb.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-core/introspection/pb/introspection.pb.go rename to vendor/github.com/libp2p/go-libp2p/core/introspection/pb/introspection.pb.go index 6af5361da..b8c609d82 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/introspection/pb/introspection.pb.go +++ b/vendor/github.com/libp2p/go-libp2p/core/introspection/pb/introspection.pb.go @@ -397,11 +397,12 @@ func (m *ResultCounter) GetErr() uint32 { // // time past -> present an event 16 min ago // ======================================================X================>> -// | | 1m -// | |---| 5m -// | |-------------| 15m -// |------------X---------------| 30m -// |------------------------------------------X---------------| 60m +// +// | | 1m +// | |---| 5m +// | |-------------| 15m +// |------------X---------------| 30m +// |------------------------------------------X---------------| 60m type SlidingCounter struct { Over_1M uint32 `protobuf:"varint,1,opt,name=over_1m,json=over1m,proto3" json:"over_1m,omitempty"` Over_5M uint32 `protobuf:"varint,2,opt,name=over_5m,json=over5m,proto3" json:"over_5m,omitempty"` diff --git a/vendor/github.com/libp2p/go-libp2p-core/introspection/pb/introspection.proto b/vendor/github.com/libp2p/go-libp2p/core/introspection/pb/introspection.proto similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/introspection/pb/introspection.proto rename to vendor/github.com/libp2p/go-libp2p/core/introspection/pb/introspection.proto diff --git a/vendor/github.com/libp2p/go-libp2p-core/metrics/bandwidth.go b/vendor/github.com/libp2p/go-libp2p/core/metrics/bandwidth.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-core/metrics/bandwidth.go rename to vendor/github.com/libp2p/go-libp2p/core/metrics/bandwidth.go index 399d1fb41..3532bf5ee 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/metrics/bandwidth.go +++ b/vendor/github.com/libp2p/go-libp2p/core/metrics/bandwidth.go @@ -6,8 +6,8 @@ import ( "github.com/libp2p/go-flow-metrics" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // BandwidthCounter tracks incoming and outgoing data transferred by the local peer. diff --git a/vendor/github.com/libp2p/go-libp2p-core/metrics/reporter.go b/vendor/github.com/libp2p/go-libp2p/core/metrics/reporter.go similarity index 90% rename from vendor/github.com/libp2p/go-libp2p-core/metrics/reporter.go rename to vendor/github.com/libp2p/go-libp2p/core/metrics/reporter.go index 860345d63..466dff9d1 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/metrics/reporter.go +++ b/vendor/github.com/libp2p/go-libp2p/core/metrics/reporter.go @@ -2,8 +2,8 @@ package metrics import ( - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // Stats represents a point-in-time snapshot of bandwidth metrics. diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/conn.go b/vendor/github.com/libp2p/go-libp2p/core/network/conn.go similarity index 94% rename from vendor/github.com/libp2p/go-libp2p-core/network/conn.go rename to vendor/github.com/libp2p/go-libp2p/core/network/conn.go index b131bcc79..8554493e2 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/network/conn.go +++ b/vendor/github.com/libp2p/go-libp2p/core/network/conn.go @@ -4,8 +4,8 @@ import ( "context" "io" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) @@ -13,7 +13,8 @@ import ( // Conn is a connection to a remote peer. It multiplexes streams. // Usually there is no need to use a Conn directly, but it may // be useful to get information about the peer on the other side: -// stream.Conn().RemotePeer() +// +// stream.Conn().RemotePeer() type Conn interface { io.Closer diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/context.go b/vendor/github.com/libp2p/go-libp2p/core/network/context.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/network/context.go rename to vendor/github.com/libp2p/go-libp2p/core/network/context.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/errors.go b/vendor/github.com/libp2p/go-libp2p/core/network/errors.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/network/errors.go rename to vendor/github.com/libp2p/go-libp2p/core/network/errors.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/mux.go b/vendor/github.com/libp2p/go-libp2p/core/network/mux.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/network/mux.go rename to vendor/github.com/libp2p/go-libp2p/core/network/mux.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/nattype.go b/vendor/github.com/libp2p/go-libp2p/core/network/nattype.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/network/nattype.go rename to vendor/github.com/libp2p/go-libp2p/core/network/nattype.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/network.go b/vendor/github.com/libp2p/go-libp2p/core/network/network.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-core/network/network.go rename to vendor/github.com/libp2p/go-libp2p/core/network/network.go index 7d5373f35..bf96697d5 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/network/network.go +++ b/vendor/github.com/libp2p/go-libp2p/core/network/network.go @@ -10,8 +10,8 @@ import ( "io" "time" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/notifee.go b/vendor/github.com/libp2p/go-libp2p/core/network/notifee.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/network/notifee.go rename to vendor/github.com/libp2p/go-libp2p/core/network/notifee.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/rcmgr.go b/vendor/github.com/libp2p/go-libp2p/core/network/rcmgr.go similarity index 88% rename from vendor/github.com/libp2p/go-libp2p-core/network/rcmgr.go rename to vendor/github.com/libp2p/go-libp2p/core/network/rcmgr.go index 5350d47c9..b60925756 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/network/rcmgr.go +++ b/vendor/github.com/libp2p/go-libp2p/core/network/rcmgr.go @@ -1,8 +1,8 @@ package network import ( - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/multiformats/go-multiaddr" ) @@ -15,16 +15,17 @@ import ( // Management Scopes, whereby resource usage is constrained by a DAG of scopes, // The following diagram illustrates the structure of the resource constraint DAG: // System -// +------------> Transient.............+................+ -// | . . -// +------------> Service------------- . ----------+ . -// | . | . -// +-------------> Protocol----------- . ----------+ . -// | . | . -// +--------------> Peer \ | . -// +------------> Connection | . -// | \ \ -// +---------------------------> Stream +// +// +------------> Transient.............+................+ +// | . . +// +------------> Service------------- . ----------+ . +// | . | . +// +-------------> Protocol----------- . ----------+ . +// | . | . +// +--------------> Peer \ | . +// +------------> Connection | . +// | \ \ +// +---------------------------> Stream // // The basic resources accounted by the ResourceManager include memory, streams, connections, // and file descriptors. These account for both space and time used by @@ -59,16 +60,16 @@ import ( // scopes can form trees, with nested spans. // // Typical Usage: -// - Low level components of the system (transports, muxers) all have access to the resource -// manager and create connection and stream scopes through it. These scopes are accessible -// to the user, albeit with a narrower interface, through Conn and Stream objects who have -// a Scope method. -// - Services typically center around streams, where the programmer can attach streams to a -// particular service. They can also directly reserve memory for a service by accessing the -// service scope using the ResourceManager interface. -// - Applications that want to account for their network resource usage can reserve memory, -// typically using a span, directly in the System or a Service scope; they can also -// opt to use appropriate steam scopes for streams that they create or own. +// - Low level components of the system (transports, muxers) all have access to the resource +// manager and create connection and stream scopes through it. These scopes are accessible +// to the user, albeit with a narrower interface, through Conn and Stream objects who have +// a Scope method. +// - Services typically center around streams, where the programmer can attach streams to a +// particular service. They can also directly reserve memory for a service by accessing the +// service scope using the ResourceManager interface. +// - Applications that want to account for their network resource usage can reserve memory, +// typically using a span, directly in the System or a Service scope; they can also +// opt to use appropriate steam scopes for streams that they create or own. // // User Serviceable Parts: the user has the option to specify their own implementation of the // interface. We provide a canonical implementation in the go-libp2p-resource-manager package. @@ -76,7 +77,8 @@ import ( // or dynamic. // // WARNING The ResourceManager interface is considered experimental and subject to change -// in subsequent releases. +// +// in subsequent releases. type ResourceManager interface { ResourceScopeViewer @@ -172,12 +174,13 @@ type ResourceScope interface { // when the programmer calls Done. // // Example: -// s, err := someScope.BeginSpan() -// if err != nil { ... } -// defer s.Done() // -// if err := s.ReserveMemory(...); err != nil { ... } -// // ... use memory +// s, err := someScope.BeginSpan() +// if err != nil { ... } +// defer s.Done() +// +// if err := s.ReserveMemory(...); err != nil { ... } +// // ... use memory type ResourceScopeSpan interface { ResourceScope // Done ends the span and releases associated resources. diff --git a/vendor/github.com/libp2p/go-libp2p-core/network/stream.go b/vendor/github.com/libp2p/go-libp2p/core/network/stream.go similarity index 94% rename from vendor/github.com/libp2p/go-libp2p-core/network/stream.go rename to vendor/github.com/libp2p/go-libp2p/core/network/stream.go index d1f928bfe..62e230034 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/network/stream.go +++ b/vendor/github.com/libp2p/go-libp2p/core/network/stream.go @@ -1,7 +1,7 @@ package network import ( - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/protocol" ) // Stream represents a bidirectional channel between two agents in diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo.go b/vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo.go rename to vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo_serde.go b/vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo_serde.go similarity index 95% rename from vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo_serde.go rename to vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo_serde.go index eae253d12..a848ea6c6 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/peer/addrinfo_serde.go +++ b/vendor/github.com/libp2p/go-libp2p/core/peer/addrinfo_serde.go @@ -3,7 +3,8 @@ package peer import ( "encoding/json" - "github.com/libp2p/go-libp2p-core/internal/catch" + "github.com/libp2p/go-libp2p/core/internal/catch" + ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/pb/Makefile b/vendor/github.com/libp2p/go-libp2p/core/peer/pb/Makefile similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/peer/pb/Makefile rename to vendor/github.com/libp2p/go-libp2p/core/peer/pb/Makefile diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/pb/peer_record.pb.go b/vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.pb.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-core/peer/pb/peer_record.pb.go rename to vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.pb.go index dd0755ef7..36040c3c2 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/peer/pb/peer_record.pb.go +++ b/vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.pb.go @@ -5,10 +5,11 @@ package peer_pb import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. @@ -28,7 +29,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // // PeerRecords are designed to be serialized to bytes and placed inside of // SignedEnvelopes before sharing with other peers. -// See https://github.com/libp2p/go-libp2p-core/record/pb/envelope.proto for +// See https://github.com/libp2p/go-libp2p/core/record/pb/envelope.proto for // the SignedEnvelope definition. type PeerRecord struct { // peer_id contains a libp2p peer id in its binary representation. diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/pb/peer_record.proto b/vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto similarity index 94% rename from vendor/github.com/libp2p/go-libp2p-core/peer/pb/peer_record.proto rename to vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto index fb2835d8e..55dd43a2b 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/peer/pb/peer_record.proto +++ b/vendor/github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto @@ -8,7 +8,7 @@ package peer.pb; // // PeerRecords are designed to be serialized to bytes and placed inside of // SignedEnvelopes before sharing with other peers. -// See https://github.com/libp2p/go-libp2p-core/record/pb/envelope.proto for +// See https://github.com/libp2p/go-libp2p/core/record/pb/envelope.proto for // the SignedEnvelope definition. message PeerRecord { diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/peer.go b/vendor/github.com/libp2p/go-libp2p/core/peer/peer.go similarity index 93% rename from vendor/github.com/libp2p/go-libp2p-core/peer/peer.go rename to vendor/github.com/libp2p/go-libp2p/core/peer/peer.go index 7d4bdfff8..7bd4f8d24 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/peer/peer.go +++ b/vendor/github.com/libp2p/go-libp2p/core/peer/peer.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/ipfs/go-cid" - ic "github.com/libp2p/go-libp2p-core/crypto" + ic "github.com/libp2p/go-libp2p/core/crypto" b58 "github.com/mr-tron/base58/base58" mc "github.com/multiformats/go-multicodec" mh "github.com/multiformats/go-multihash" @@ -42,19 +42,20 @@ const maxInlineKeyLength = 42 type ID string // Pretty returns a base58-encoded string representation of the ID. +// Deprecated: use String() instead. func (id ID) Pretty() string { - return Encode(id) + return id.String() } // Loggable returns a pretty peer ID string in loggable JSON format. func (id ID) Loggable() map[string]interface{} { return map[string]interface{}{ - "peerID": id.Pretty(), + "peerID": id.String(), } } func (id ID) String() string { - return id.Pretty() + return b58.Encode([]byte(id)) } // ShortString prints out the peer ID. @@ -64,7 +65,7 @@ func (id ID) String() string { // IDs safely. Then any peer.ID type found in the // codebase is known to be correct. func (id ID) ShortString() string { - pid := id.Pretty() + pid := id.String() if len(pid) <= 10 { return fmt.Sprintf("", pid) } @@ -113,15 +114,6 @@ func (id ID) Validate() error { return nil } -// IDFromString casts a string to the ID type, and validates -// the value to make sure it is a multihash. -func IDFromString(s string) (ID, error) { - if _, err := mh.Cast([]byte(s)); err != nil { - return ID(""), err - } - return ID(s), nil -} - // IDFromBytes casts a byte slice to the ID type, and validates // the value to make sure it is a multihash. func IDFromBytes(b []byte) (ID, error) { @@ -157,8 +149,10 @@ func Decode(s string) (ID, error) { // // At the moment, it base58 encodes the peer ID but, in the future, it will // switch to encoding it as a CID by default. +// +// Deprecated: use id.String instead. func Encode(id ID) string { - return b58.Encode([]byte(id)) + return id.String() } // FromCid converts a CID to a peer ID, if possible. diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/peer_serde.go b/vendor/github.com/libp2p/go-libp2p/core/peer/peer_serde.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/peer/peer_serde.go rename to vendor/github.com/libp2p/go-libp2p/core/peer/peer_serde.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/peer/record.go b/vendor/github.com/libp2p/go-libp2p/core/peer/record.go similarity index 90% rename from vendor/github.com/libp2p/go-libp2p-core/peer/record.go rename to vendor/github.com/libp2p/go-libp2p/core/peer/record.go index aae1d76ad..9f8861af8 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/peer/record.go +++ b/vendor/github.com/libp2p/go-libp2p/core/peer/record.go @@ -5,9 +5,9 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/internal/catch" - pb "github.com/libp2p/go-libp2p-core/peer/pb" - "github.com/libp2p/go-libp2p-core/record" + "github.com/libp2p/go-libp2p/core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/peer/pb" + "github.com/libp2p/go-libp2p/core/record" ma "github.com/multiformats/go-multiaddr" @@ -40,14 +40,14 @@ var PeerRecordEnvelopePayloadType = []byte{0x03, 0x01} // a PeerRecord with a timestamp-based Seq value. The other PeerRecord fields should // be set by the caller: // -// rec := peer.NewPeerRecord() -// rec.PeerID = aPeerID -// rec.Addrs = someAddrs +// rec := peer.NewPeerRecord() +// rec.PeerID = aPeerID +// rec.Addrs = someAddrs // // Alternatively, you can construct a PeerRecord struct directly and use the TimestampSeq // helper to set the Seq field: // -// rec := peer.PeerRecord{PeerID: aPeerID, Addrs: someAddrs, Seq: peer.TimestampSeq()} +// rec := peer.PeerRecord{PeerID: aPeerID, Addrs: someAddrs, Seq: peer.TimestampSeq()} // // Failing to set the Seq field will not result in an error, however, a PeerRecord with a // Seq value of zero may be ignored or rejected by other peers. @@ -59,28 +59,27 @@ var PeerRecordEnvelopePayloadType = []byte{0x03, 0x01} // To share a PeerRecord, first call Sign to wrap the record in a Envelope // and sign it with the local peer's private key: // -// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs} -// envelope, err := rec.Sign(myPrivateKey) +// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs} +// envelope, err := rec.Sign(myPrivateKey) // // The resulting record.Envelope can be marshalled to a []byte and shared // publicly. As a convenience, the MarshalSigned method will produce the // Envelope and marshal it to a []byte in one go: // -// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs} -// recordBytes, err := rec.MarshalSigned(myPrivateKey) +// rec := &PeerRecord{PeerID: myPeerId, Addrs: myAddrs} +// recordBytes, err := rec.MarshalSigned(myPrivateKey) // // To validate and unmarshal a signed PeerRecord from a remote peer, // "consume" the containing envelope, which will return both the // routing.Envelope and the inner Record. The Record must be cast to // a PeerRecord pointer before use: // -// envelope, untypedRecord, err := ConsumeEnvelope(envelopeBytes, PeerRecordEnvelopeDomain) -// if err != nil { -// handleError(err) -// return -// } -// peerRec := untypedRecord.(*PeerRecord) -// +// envelope, untypedRecord, err := ConsumeEnvelope(envelopeBytes, PeerRecordEnvelopeDomain) +// if err != nil { +// handleError(err) +// return +// } +// peerRec := untypedRecord.(*PeerRecord) type PeerRecord struct { // PeerID is the ID of the peer this record pertains to. PeerID ID diff --git a/vendor/github.com/libp2p/go-libp2p-core/peerstore/helpers.go b/vendor/github.com/libp2p/go-libp2p/core/peerstore/helpers.go similarity index 87% rename from vendor/github.com/libp2p/go-libp2p-core/peerstore/helpers.go rename to vendor/github.com/libp2p/go-libp2p/core/peerstore/helpers.go index e41cf781f..92e522d58 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/peerstore/helpers.go +++ b/vendor/github.com/libp2p/go-libp2p/core/peerstore/helpers.go @@ -1,7 +1,7 @@ package peerstore import ( - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // AddrInfos returns an AddrInfo for each specified peer ID, in-order. diff --git a/vendor/github.com/libp2p/go-libp2p-core/peerstore/peerstore.go b/vendor/github.com/libp2p/go-libp2p/core/peerstore/peerstore.go similarity index 97% rename from vendor/github.com/libp2p/go-libp2p-core/peerstore/peerstore.go rename to vendor/github.com/libp2p/go-libp2p/core/peerstore/peerstore.go index f93d8fb5d..213513bcd 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/peerstore/peerstore.go +++ b/vendor/github.com/libp2p/go-libp2p/core/peerstore/peerstore.go @@ -9,9 +9,9 @@ import ( "math" "time" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/record" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/record" ma "github.com/multiformats/go-multiaddr" ) @@ -142,10 +142,9 @@ type AddrBook interface { // certified addresses, callers should use the GetCertifiedAddrBook helper or // type-assert on the CertifiedAddrBook interface: // -// if cab, ok := aPeerstore.(CertifiedAddrBook); ok { -// cab.ConsumePeerRecord(signedPeerRecord, aTTL) -// } -// +// if cab, ok := aPeerstore.(CertifiedAddrBook); ok { +// cab.ConsumePeerRecord(signedPeerRecord, aTTL) +// } type CertifiedAddrBook interface { // ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in // a record.Envelope), which will expire after the given TTL. diff --git a/vendor/github.com/libp2p/go-libp2p-core/pnet/codec.go b/vendor/github.com/libp2p/go-libp2p/core/pnet/codec.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/pnet/codec.go rename to vendor/github.com/libp2p/go-libp2p/core/pnet/codec.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/pnet/env.go b/vendor/github.com/libp2p/go-libp2p/core/pnet/env.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/pnet/env.go rename to vendor/github.com/libp2p/go-libp2p/core/pnet/env.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/pnet/error.go b/vendor/github.com/libp2p/go-libp2p/core/pnet/error.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/pnet/error.go rename to vendor/github.com/libp2p/go-libp2p/core/pnet/error.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/pnet/protector.go b/vendor/github.com/libp2p/go-libp2p/core/pnet/protector.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/pnet/protector.go rename to vendor/github.com/libp2p/go-libp2p/core/pnet/protector.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/protocol/id.go b/vendor/github.com/libp2p/go-libp2p/core/protocol/id.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/protocol/id.go rename to vendor/github.com/libp2p/go-libp2p/core/protocol/id.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/protocol/switch.go b/vendor/github.com/libp2p/go-libp2p/core/protocol/switch.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/protocol/switch.go rename to vendor/github.com/libp2p/go-libp2p/core/protocol/switch.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/record/envelope.go b/vendor/github.com/libp2p/go-libp2p/core/record/envelope.go similarity index 93% rename from vendor/github.com/libp2p/go-libp2p-core/record/envelope.go rename to vendor/github.com/libp2p/go-libp2p/core/record/envelope.go index df1eee7a3..38811994b 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/record/envelope.go +++ b/vendor/github.com/libp2p/go-libp2p/core/record/envelope.go @@ -6,9 +6,9 @@ import ( "fmt" "sync" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/internal/catch" - pb "github.com/libp2p/go-libp2p-core/record/pb" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/internal/catch" + pb "github.com/libp2p/go-libp2p/core/record/pb" pool "github.com/libp2p/go-buffer-pool" @@ -94,15 +94,15 @@ func Seal(rec Record, privateKey crypto.PrivKey) (*Envelope, error) { // You can type assert on the returned Record to convert it to an instance of the concrete // Record type: // -// envelope, rec, err := ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain) -// if err != nil { -// handleError(envelope, err) // envelope may be non-nil, even if errors occur! -// return -// } -// peerRec, ok := rec.(*peer.PeerRecord) -// if ok { -// doSomethingWithPeerRecord(peerRec) -// } +// envelope, rec, err := ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain) +// if err != nil { +// handleError(envelope, err) // envelope may be non-nil, even if errors occur! +// return +// } +// peerRec, ok := rec.(*peer.PeerRecord) +// if ok { +// doSomethingWithPeerRecord(peerRec) +// } // // Important: you MUST check the error value before using the returned Envelope. In some error // cases, including when the envelope signature is invalid, both the Envelope and an error will @@ -140,12 +140,12 @@ func ConsumeEnvelope(data []byte, domain string) (envelope *Envelope, rec Record // responsibility to determine whether the given Record type is able to unmarshal the payload // correctly. // -// rec := &MyRecordType{} -// envelope, err := ConsumeTypedEnvelope(envelopeBytes, rec) -// if err != nil { -// handleError(envelope, err) -// } -// doSomethingWithRecord(rec) +// rec := &MyRecordType{} +// envelope, err := ConsumeTypedEnvelope(envelopeBytes, rec) +// if err != nil { +// handleError(envelope, err) +// } +// doSomethingWithRecord(rec) // // Important: you MUST check the error value before using the returned Envelope. In some error // cases, including when the envelope signature is invalid, both the Envelope and an error will diff --git a/vendor/github.com/libp2p/go-libp2p-core/record/pb/Makefile b/vendor/github.com/libp2p/go-libp2p/core/record/pb/Makefile similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/record/pb/Makefile rename to vendor/github.com/libp2p/go-libp2p/core/record/pb/Makefile diff --git a/vendor/github.com/libp2p/go-libp2p-core/record/pb/envelope.pb.go b/vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.pb.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-core/record/pb/envelope.pb.go rename to vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.pb.go index 412809f13..a99902175 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/record/pb/envelope.pb.go +++ b/vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.pb.go @@ -5,11 +5,12 @@ package record_pb import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" io "io" math "math" math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/vendor/github.com/libp2p/go-libp2p-core/record/pb/envelope.proto b/vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.proto similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/record/pb/envelope.proto rename to vendor/github.com/libp2p/go-libp2p/core/record/pb/envelope.proto diff --git a/vendor/github.com/libp2p/go-libp2p-core/record/record.go b/vendor/github.com/libp2p/go-libp2p/core/record/record.go similarity index 93% rename from vendor/github.com/libp2p/go-libp2p-core/record/record.go rename to vendor/github.com/libp2p/go-libp2p/core/record/record.go index af30a47e1..704227f2a 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/record/record.go +++ b/vendor/github.com/libp2p/go-libp2p/core/record/record.go @@ -4,7 +4,7 @@ import ( "errors" "reflect" - "github.com/libp2p/go-libp2p-core/internal/catch" + "github.com/libp2p/go-libp2p/core/internal/catch" ) var ( @@ -59,15 +59,14 @@ type Record interface { // a pointer type. Registration should be done in the init function of the package // where the Record type is defined: // -// package hello_record -// import record "github.com/libp2p/go-libp2p-core/record" +// package hello_record +// import record "github.com/libp2p/go-libp2p/core/record" // -// func init() { -// record.RegisterType(&HelloRecord{}) -// } -// -// type HelloRecord struct { } // etc.. +// func init() { +// record.RegisterType(&HelloRecord{}) +// } // +// type HelloRecord struct { } // etc.. func RegisterType(prototype Record) { payloadTypeRegistry[string(prototype.Codec())] = getValueType(prototype) } diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/options.go b/vendor/github.com/libp2p/go-libp2p/core/routing/options.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/routing/options.go rename to vendor/github.com/libp2p/go-libp2p/core/routing/options.go diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/query.go b/vendor/github.com/libp2p/go-libp2p/core/routing/query.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-core/routing/query.go rename to vendor/github.com/libp2p/go-libp2p/core/routing/query.go index 26743af09..72791b527 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/routing/query.go +++ b/vendor/github.com/libp2p/go-libp2p/core/routing/query.go @@ -4,7 +4,7 @@ import ( "context" "sync" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // QueryEventType indicates the query event's type. diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/query_serde.go b/vendor/github.com/libp2p/go-libp2p/core/routing/query_serde.go similarity index 89% rename from vendor/github.com/libp2p/go-libp2p-core/routing/query_serde.go rename to vendor/github.com/libp2p/go-libp2p/core/routing/query_serde.go index 18c3f91a0..6b566e0ca 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/routing/query_serde.go +++ b/vendor/github.com/libp2p/go-libp2p/core/routing/query_serde.go @@ -3,12 +3,12 @@ package routing import ( "encoding/json" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) func (qe *QueryEvent) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ - "ID": peer.Encode(qe.ID), + "ID": qe.ID.String(), "Type": int(qe.Type), "Responses": qe.Responses, "Extra": qe.Extra, diff --git a/vendor/github.com/libp2p/go-libp2p-core/routing/routing.go b/vendor/github.com/libp2p/go-libp2p/core/routing/routing.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-core/routing/routing.go rename to vendor/github.com/libp2p/go-libp2p/core/routing/routing.go index 807f968ec..07437b5df 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/routing/routing.go +++ b/vendor/github.com/libp2p/go-libp2p/core/routing/routing.go @@ -5,8 +5,8 @@ import ( "context" "errors" - ci "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + ci "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" cid "github.com/ipfs/go-cid" ) diff --git a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/insecure.go b/vendor/github.com/libp2p/go-libp2p/core/sec/insecure/insecure.go similarity index 97% rename from vendor/github.com/libp2p/go-libp2p-core/sec/insecure/insecure.go rename to vendor/github.com/libp2p/go-libp2p/core/sec/insecure/insecure.go index 1fd52457c..12bd1842b 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/insecure.go +++ b/vendor/github.com/libp2p/go-libp2p/core/sec/insecure/insecure.go @@ -9,12 +9,12 @@ import ( "io" "net" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-msgio" + ci "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + pb "github.com/libp2p/go-libp2p/core/sec/insecure/pb" - ci "github.com/libp2p/go-libp2p-core/crypto" - pb "github.com/libp2p/go-libp2p-core/sec/insecure/pb" + "github.com/libp2p/go-msgio" ) // ID is the multistream-select protocol ID that should be used when identifying diff --git a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/Makefile b/vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/Makefile similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/Makefile rename to vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/Makefile diff --git a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/plaintext.pb.go b/vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.pb.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/plaintext.pb.go rename to vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.pb.go index 4c5af1837..cd8719d11 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/plaintext.pb.go +++ b/vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.pb.go @@ -5,11 +5,12 @@ package plaintext_pb import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" - pb "github.com/libp2p/go-libp2p-core/crypto/pb" io "io" math "math" math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" + pb "github.com/libp2p/go-libp2p/core/crypto/pb" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/plaintext.proto b/vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.proto similarity index 68% rename from vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/plaintext.proto rename to vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.proto index 1e299df58..0e792b3cf 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/sec/insecure/pb/plaintext.proto +++ b/vendor/github.com/libp2p/go-libp2p/core/sec/insecure/pb/plaintext.proto @@ -2,7 +2,7 @@ syntax = "proto2"; package plaintext.pb; -import "github.com/libp2p/go-libp2p-core/crypto/pb/crypto.proto"; +import "github.com/libp2p/go-libp2p/core/crypto/pb/crypto.proto"; message Exchange { optional bytes id = 1; diff --git a/vendor/github.com/libp2p/go-libp2p-core/sec/security.go b/vendor/github.com/libp2p/go-libp2p/core/sec/security.go similarity index 94% rename from vendor/github.com/libp2p/go-libp2p-core/sec/security.go rename to vendor/github.com/libp2p/go-libp2p/core/sec/security.go index a4cd7a2e3..c192a56a9 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/sec/security.go +++ b/vendor/github.com/libp2p/go-libp2p/core/sec/security.go @@ -5,8 +5,8 @@ import ( "context" "net" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // SecureConn is an authenticated, encrypted connection. diff --git a/vendor/github.com/libp2p/go-libp2p-core/transport/transport.go b/vendor/github.com/libp2p/go-libp2p/core/transport/transport.go similarity index 93% rename from vendor/github.com/libp2p/go-libp2p-core/transport/transport.go rename to vendor/github.com/libp2p/go-libp2p/core/transport/transport.go index 91cb75a3d..ad2ee6649 100644 --- a/vendor/github.com/libp2p/go-libp2p-core/transport/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/core/transport/transport.go @@ -6,8 +6,8 @@ import ( "context" "net" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -77,6 +77,12 @@ type Transport interface { Proxy() bool } +// Resolver can be optionally implemented by transports that want to resolve or transform the +// multiaddr. +type Resolver interface { + Resolve(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error) +} + // Listener is an interface closely resembling the net.Listener interface. The // only real difference is that Accept() returns Conn's of the type in this // package, and also exposes a Multiaddr method as opposed to a regular Addr diff --git a/vendor/github.com/libp2p/go-libp2p/defaults.go b/vendor/github.com/libp2p/go-libp2p/defaults.go index d95a6a958..c36c760cc 100644 --- a/vendor/github.com/libp2p/go-libp2p/defaults.go +++ b/vendor/github.com/libp2p/go-libp2p/defaults.go @@ -5,6 +5,9 @@ package libp2p import ( "crypto/rand" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" "github.com/libp2p/go-libp2p/p2p/net/connmgr" "github.com/libp2p/go-libp2p/p2p/security/noise" @@ -13,11 +16,8 @@ import ( "github.com/libp2p/go-libp2p/p2p/transport/tcp" ws "github.com/libp2p/go-libp2p/p2p/transport/websocket" - "github.com/libp2p/go-libp2p-core/crypto" - - "github.com/libp2p/go-libp2p-peerstore/pstoremem" - rcmgr "github.com/libp2p/go-libp2p-resource-manager" "github.com/multiformats/go-multiaddr" + madns "github.com/multiformats/go-multiaddr-dns" ) // DefaultSecurity is the default security option. @@ -56,7 +56,7 @@ var DefaultPeerstore Option = func(cfg *Config) error { // RandomIdentity generates a random identity. (default behaviour) var RandomIdentity = func(cfg *Config) error { - priv, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, rand.Reader) + priv, _, err := crypto.GenerateEd25519Key(rand.Reader) if err != nil { return err } @@ -65,18 +65,28 @@ var RandomIdentity = func(cfg *Config) error { // DefaultListenAddrs configures libp2p to use default listen address. var DefaultListenAddrs = func(cfg *Config) error { - defaultIP4ListenAddr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/tcp/0") + defaultIP4TCPListenAddr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/tcp/0") + if err != nil { + return err + } + defaultIP4QUICListenAddr, err := multiaddr.NewMultiaddr("/ip4/0.0.0.0/udp/0/quic") if err != nil { return err } - defaultIP6ListenAddr, err := multiaddr.NewMultiaddr("/ip6/::/tcp/0") + defaultIP6TCPListenAddr, err := multiaddr.NewMultiaddr("/ip6/::/tcp/0") + if err != nil { + return err + } + defaultIP6QUICListenAddr, err := multiaddr.NewMultiaddr("/ip6/::/udp/0/quic") if err != nil { return err } return cfg.Apply(ListenAddrs( - defaultIP4ListenAddr, - defaultIP6ListenAddr, + defaultIP4TCPListenAddr, + defaultIP4QUICListenAddr, + defaultIP6TCPListenAddr, + defaultIP6QUICListenAddr, )) } @@ -107,6 +117,11 @@ var DefaultConnectionManager = func(cfg *Config) error { return cfg.Apply(ConnectionManager(mgr)) } +// DefaultMultiaddrResolver creates a default connection manager +var DefaultMultiaddrResolver = func(cfg *Config) error { + return cfg.Apply(MultiaddrResolver(madns.DefaultResolver)) +} + // Complete list of default options and when to fallback on them. // // Please *DON'T* specify default options any other way. Putting this all here @@ -151,6 +166,10 @@ var defaults = []struct { fallback: func(cfg *Config) bool { return cfg.ConnManager == nil }, opt: DefaultConnectionManager, }, + { + fallback: func(cfg *Config) bool { return cfg.MultiaddrResolver == nil }, + opt: DefaultMultiaddrResolver, + }, } // Defaults configures libp2p to use the default options. Can be combined with diff --git a/vendor/github.com/libp2p/go-libp2p/libp2p.go b/vendor/github.com/libp2p/go-libp2p/libp2p.go index 7fdd3b71f..d77c3b9b2 100644 --- a/vendor/github.com/libp2p/go-libp2p/libp2p.go +++ b/vendor/github.com/libp2p/go-libp2p/libp2p.go @@ -2,8 +2,7 @@ package libp2p import ( "github.com/libp2p/go-libp2p/config" - - "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p/core/host" ) // Config describes a set of settings for a libp2p node. diff --git a/vendor/github.com/libp2p/go-libp2p/limits.go b/vendor/github.com/libp2p/go-libp2p/limits.go index fd71bca76..cf81fa762 100644 --- a/vendor/github.com/libp2p/go-libp2p/limits.go +++ b/vendor/github.com/libp2p/go-libp2p/limits.go @@ -1,17 +1,15 @@ package libp2p import ( - "github.com/libp2p/go-libp2p-core/protocol" - + "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-libp2p/p2p/host/autonat" + rcmgr "github.com/libp2p/go-libp2p/p2p/host/resource-manager" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" circuit "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" "github.com/libp2p/go-libp2p/p2p/protocol/holepunch" "github.com/libp2p/go-libp2p/p2p/protocol/identify" "github.com/libp2p/go-libp2p/p2p/protocol/ping" - - rcmgr "github.com/libp2p/go-libp2p-resource-manager" ) // SetDefaultServiceLimits sets the default limits for bundled libp2p services diff --git a/vendor/github.com/libp2p/go-libp2p/options.go b/vendor/github.com/libp2p/go-libp2p/options.go index 312d08a24..3509c61d4 100644 --- a/vendor/github.com/libp2p/go-libp2p/options.go +++ b/vendor/github.com/libp2p/go-libp2p/options.go @@ -8,15 +8,14 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/metrics" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/pnet" - "github.com/libp2p/go-libp2p/config" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/metrics" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/pnet" "github.com/libp2p/go-libp2p/p2p/host/autorelay" bhost "github.com/libp2p/go-libp2p/p2p/host/basic" relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" @@ -245,8 +244,8 @@ func EnableRelayService(opts ...relayv2.Option) Option { // EnableAutoRelay configures libp2p to enable the AutoRelay subsystem. // // Dependencies: -// * Relay (enabled by default) -// * Routing (to find relays), or StaticRelays/DefaultStaticRelays. +// - Relay (enabled by default) +// - Routing (to find relays), or StaticRelays/DefaultStaticRelays. // // This subsystem performs automatic address rewriting to advertise relay addresses when it // detects that the node is publicly unreachable (e.g. behind a NAT). @@ -330,7 +329,7 @@ func AutoNATServiceRateLimit(global, perPeer int, interval time.Duration) Option // to actively reject inbound/outbound connections based on the lifecycle stage // of the connection. // -// For more information, refer to go-libp2p-core.ConnectionGater. +// For more information, refer to go-libp2p/core.ConnectionGater. func ConnectionGater(cg connmgr.ConnectionGater) Option { return func(cfg *Config) error { if cfg.ConnectionGater != nil { @@ -342,7 +341,7 @@ func ConnectionGater(cg connmgr.ConnectionGater) Option { } // ResourceManager configures libp2p to use the given ResourceManager. -// When using the go-libp2p-resource-manager implementation of the ResourceManager interface, +// When using the p2p/host/resource-manager implementation of the ResourceManager interface, // it is recommended to set limits for libp2p protocol by calling SetDefaultServiceLimits. func ResourceManager(rcmgr network.ResourceManager) Option { return func(cfg *Config) error { @@ -415,6 +414,15 @@ var NoTransports = func(cfg *Config) error { return nil } +// ProtocolVersion sets the protocolVersion string required by the +// libp2p Identify protocol. +func ProtocolVersion(s string) Option { + return func(cfg *Config) error { + cfg.ProtocolVersion = s + return nil + } +} + // UserAgent sets the libp2p user-agent sent along with the identify protocol func UserAgent(userAgent string) Option { return func(cfg *Config) error { @@ -436,14 +444,14 @@ func MultiaddrResolver(rslv *madns.Resolver) Option { // to create direct/NAT-traversed connections with other peers. (default: disabled) // // Dependencies: -// * Relay (enabled by default) +// - Relay (enabled by default) // // This subsystem performs two functions: // -// 1. On receiving an inbound Relay connection, it attempts to create a direct connection with the remote peer -// by initiating and co-ordinating a hole punch over the Relayed connection. -// 2. If a peer sees a request to co-ordinate a hole punch on an outbound Relay connection, -// it will participate in the hole-punch to create a direct connection with the remote peer. +// 1. On receiving an inbound Relay connection, it attempts to create a direct connection with the remote peer +// by initiating and co-ordinating a hole punch over the Relayed connection. +// 2. If a peer sees a request to co-ordinate a hole punch on an outbound Relay connection, +// it will participate in the hole-punch to create a direct connection with the remote peer. // // If the hole punch is successful, all new streams will thereafter be created on the hole-punched connection. // The Relayed connection will eventually be closed after a grace period. diff --git a/vendor/github.com/libp2p/go-libp2p/options_filter.go b/vendor/github.com/libp2p/go-libp2p/options_filter.go index c6b8175d8..1f94ac3f0 100644 --- a/vendor/github.com/libp2p/go-libp2p/options_filter.go +++ b/vendor/github.com/libp2p/go-libp2p/options_filter.go @@ -1,10 +1,10 @@ package libp2p import ( - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/control" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/control" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffcache.go b/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffcache.go index 9aacfdadc..82c07241f 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffcache.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffcache.go @@ -6,8 +6,8 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffconnector.go b/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffconnector.go index 62ac49897..8a355a2d9 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffconnector.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/discovery/backoff/backoffconnector.go @@ -5,10 +5,10 @@ import ( "sync" "time" - lru "github.com/hashicorp/golang-lru" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + lru "github.com/hashicorp/golang-lru" ) // BackoffConnector is a utility to connect to peers, but only if we have not recently tried connecting to them already diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/autonat.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/autonat.go index 3439e49b5..0fd8b0ec4 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/autonat.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/autonat.go @@ -7,11 +7,11 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-eventbus" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/p2p/host/eventbus" logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/client.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/client.go index f4eb08ad3..3edbeb50e 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/client.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/client.go @@ -5,13 +5,12 @@ import ( "fmt" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-msgio/protoio" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/dialpolicy.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/dialpolicy.go index 653882cba..961522955 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/dialpolicy.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/dialpolicy.go @@ -3,7 +3,8 @@ package autonat import ( "net" - "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p/core/host" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/interface.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/interface.go index 2551f2c5a..f4c89beab 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/interface.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/interface.go @@ -4,8 +4,8 @@ import ( "context" "io" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/notify.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/notify.go index fb8e980af..a57bf1565 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/notify.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/notify.go @@ -1,7 +1,7 @@ package autonat import ( - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/options.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/options.go index 390533137..0935dc233 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/options.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/options.go @@ -4,8 +4,8 @@ import ( "errors" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" ) // config holds configurable options for the autonat subsystem. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/proto.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/proto.go index 69ac58717..93f273cd6 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/proto.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/proto.go @@ -1,10 +1,9 @@ package autonat import ( + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/svc.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/svc.go index fc1fc3a8a..10136a7de 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/svc.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autonat/svc.go @@ -7,12 +7,11 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" pb "github.com/libp2p/go-libp2p/p2p/host/autonat/pb" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-msgio/protoio" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/addrsplosion.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/addrsplosion.go index be3be52b3..c6353b157 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/addrsplosion.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/addrsplosion.go @@ -104,8 +104,8 @@ func addrKeyAndPort(a ma.Multiaddr) (string, int) { // clean up addrsplosion // the following heuristic is used: -// - for each base address/protocol combination, if there are multiple ports advertised then -// only accept the default port if present. +// - for each base address/protocol combination, if there are multiple ports advertised then +// only accept the default port if present. // - If the default port is not present, we check for non-standard ports by tracking // private port bindings if present. // - If there is no default or private port binding, then we can't infer the correct diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/autorelay.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/autorelay.go index 370ea22b4..e4e3568ef 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/autorelay.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/autorelay.go @@ -4,13 +4,11 @@ import ( "context" "sync" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" basic "github.com/libp2p/go-libp2p/p2p/host/basic" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" ) @@ -29,8 +27,6 @@ type AutoRelay struct { relayFinder *relayFinder - peerChanOut chan peer.AddrInfo // capacity 20 - host host.Host addrsF basic.AddrsFactory } @@ -48,9 +44,8 @@ func NewAutoRelay(bhost *basic.BasicHost, opts ...Option) (*AutoRelay, error) { } } r.ctx, r.ctxCancel = context.WithCancel(context.Background()) - r.peerChanOut = make(chan peer.AddrInfo, conf.maxCandidates) r.conf = &conf - r.relayFinder = newRelayFinder(bhost, r.peerChanOut, &conf) + r.relayFinder = newRelayFinder(bhost, conf.peerSource, &conf) bhost.AddrsFactory = r.hostAddrs r.refCount.Add(1) @@ -69,25 +64,6 @@ func (r *AutoRelay) background() { } defer subReachability.Close() - var peerChan <-chan peer.AddrInfo - if len(r.conf.staticRelays) == 0 { - peerChan = r.conf.peerChan - } else { - pc := make(chan peer.AddrInfo) - peerChan = pc - r.refCount.Add(1) - go func() { - defer r.refCount.Done() - for _, sr := range r.conf.staticRelays { - select { - case pc <- sr: - case <-r.ctx.Done(): - return - } - } - }() - } - for { select { case <-r.ctx.Done(): @@ -109,17 +85,6 @@ func (r *AutoRelay) background() { r.mx.Lock() r.status = evt.Reachability r.mx.Unlock() - case pi := <-peerChan: - select { - case r.peerChanOut <- pi: // if there's space in the channel, great - default: - // no space left in the channel. Drop the oldest entry. - select { - case <-r.peerChanOut: - default: // The consumer might just have emptied the channel. Make sure we don't block in that case. - } - r.peerChanOut <- pi - } } } } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/host.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/host.go index 9a90c9e6e..740ca2362 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/host.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/host.go @@ -1,7 +1,7 @@ package autorelay import ( - "github.com/libp2p/go-libp2p-core/host" + "github.com/libp2p/go-libp2p/core/host" ) type AutoRelayHost struct { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/options.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/options.go index e6119a261..a6e9f595b 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/options.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/options.go @@ -1,15 +1,21 @@ package autorelay import ( + "context" "errors" "fmt" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" + + "github.com/benbjohnson/clock" ) type config struct { - peerChan <-chan peer.AddrInfo + clock clock.Clock + peerSource func(ctx context.Context, num int) <-chan peer.AddrInfo + // minimum interval used to call the peerSource callback + minInterval time.Duration staticRelays []peer.AddrInfo // see WithMinCandidates minCandidates int @@ -20,24 +26,28 @@ type config struct { bootDelay time.Duration // backoff is the time we wait after failing to obtain a reservation with a candidate backoff time.Duration - // If we fail to obtain a reservation more than maxAttempts, we stop trying. - maxAttempts int // Number of relays we strive to obtain a reservation with. - desiredRelays int + desiredRelays int + // see WithMaxCandidateAge + maxCandidateAge time.Duration setMinCandidates bool enableCircuitV1 bool } var defaultConfig = config{ - minCandidates: 4, - maxCandidates: 20, - bootDelay: 3 * time.Minute, - backoff: time.Hour, - maxAttempts: 3, - desiredRelays: 2, + clock: clock.New(), + minCandidates: 4, + maxCandidates: 20, + bootDelay: 3 * time.Minute, + backoff: time.Hour, + desiredRelays: 2, + maxCandidateAge: 30 * time.Minute, } -var errStaticRelaysMinCandidates = errors.New("cannot use WithMinCandidates and WithStaticRelays") +var ( + errStaticRelaysMinCandidates = errors.New("cannot use WithMinCandidates and WithStaticRelays") + errStaticRelaysPeerSource = errors.New("cannot use WithPeerSource and WithStaticRelays") +) // DefaultRelays are the known PL-operated v1 relays; will be decommissioned in 2022. var DefaultRelays = []string{ @@ -68,6 +78,9 @@ func WithStaticRelays(static []peer.AddrInfo) Option { if c.setMinCandidates { return errStaticRelaysMinCandidates } + if c.peerSource != nil { + return errStaticRelaysPeerSource + } if len(c.staticRelays) > 0 { return errors.New("can't set static relays, static relays already configured") } @@ -81,9 +94,24 @@ func WithDefaultStaticRelays() Option { return WithStaticRelays(defaultStaticRelays) } -func WithPeerSource(peerChan <-chan peer.AddrInfo) Option { +// WithPeerSource defines a callback for AutoRelay to query for more relay candidates. +// AutoRelay will call this function when it needs new candidates is connected to the desired number of +// relays, and it has enough candidates (in case we get disconnected from one of the relays). +// Implementations must send *at most* numPeers, and close the channel when they don't intend to provide +// any more peers. +// AutoRelay will not call the callback again until the channel is closed. +// Implementations should send new peers, but may send peers they sent before. AutoRelay implements +// a per-peer backoff (see WithBackoff). +// minInterval is the minimum interval this callback is called with, even if AutoRelay needs new candidates. +// The context.Context passed MAY be canceled when AutoRelay feels satisfied, it will be canceled when the node is shutting down. +// If the channel is canceled you MUST close the output channel at some point. +func WithPeerSource(f func(ctx context.Context, numPeers int) <-chan peer.AddrInfo, minInterval time.Duration) Option { return func(c *config) error { - c.peerChan = peerChan + if len(c.staticRelays) > 0 { + return errStaticRelaysPeerSource + } + c.peerSource = f + c.minInterval = minInterval return nil } } @@ -100,6 +128,9 @@ func WithNumRelays(n int) Option { func WithMaxCandidates(n int) Option { return func(c *config) error { c.maxCandidates = n + if c.minCandidates > n { + c.minCandidates = n + } return nil } } @@ -112,6 +143,9 @@ func WithMinCandidates(n int) Option { if len(c.staticRelays) > 0 { return errStaticRelaysMinCandidates } + if n > c.maxCandidates { + n = c.maxCandidates + } c.minCandidates = n c.setMinCandidates = true return nil @@ -137,15 +171,6 @@ func WithBackoff(d time.Duration) Option { } } -// WithMaxAttempts sets the number of times we attempt to obtain a reservation with a candidate. -// If we still fail to obtain a reservation, this candidate is dropped. -func WithMaxAttempts(n int) Option { - return func(c *config) error { - c.maxAttempts = n - return nil - } -} - // WithCircuitV1Support enables support for circuit v1 relays. func WithCircuitV1Support() Option { return func(c *config) error { @@ -153,3 +178,22 @@ func WithCircuitV1Support() Option { return nil } } + +// WithMaxCandidateAge sets the maximum age of a candidate. +// When we are connected to the desired number of relays, we don't ask the peer source for new candidates. +// This can lead to AutoRelay's candidate list becoming outdated, and means we won't be able +// to quickly establish a new relay connection if our existing connection breaks, if all the candidates +// have become stale. +func WithMaxCandidateAge(d time.Duration) Option { + return func(c *config) error { + c.maxCandidateAge = d + return nil + } +} + +func WithClock(cl clock.Clock) Option { + return func(c *config) error { + c.clock = cl + return nil + } +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/relay_finder.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/relay_finder.go index 48bc7f7fd..4760511bc 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/relay_finder.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/relay_finder.go @@ -10,15 +10,14 @@ import ( "golang.org/x/sync/errgroup" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" basic "github.com/libp2p/go-libp2p/p2p/host/basic" relayv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay" circuitv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client" circuitv2_proto "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) @@ -46,12 +45,6 @@ type candidate struct { added time.Time supportsRelayV2 bool ai peer.AddrInfo - numAttempts int -} - -type candidateOnBackoff struct { - candidate - nextConnAttempt time.Time } // relayFinder is a Host that uses relays for connectivity when a NAT is detected. @@ -66,13 +59,19 @@ type relayFinder struct { ctxCancel context.CancelFunc ctxCancelMx sync.Mutex - peerChan <-chan peer.AddrInfo + peerSource func(context.Context, int) <-chan peer.AddrInfo - candidateFound chan struct{} // receives every time we find a new relay candidate - candidateMx sync.Mutex - candidates map[peer.ID]*candidate - candidatesOnBackoff []*candidateOnBackoff // this slice is always sorted by the nextConnAttempt time - handleNewCandidateTrigger chan struct{} // cap: 1 + candidateFound chan struct{} // receives every time we find a new relay candidate + candidateMx sync.Mutex + candidates map[peer.ID]*candidate + backoff map[peer.ID]time.Time + maybeConnectToRelayTrigger chan struct{} // cap: 1 + // Any time _something_ hapens that might cause us to need new candidates. + // This could be + // * the disconnection of a relay + // * the failed attempt to obtain a reservation with a current candidate + // * a candidate is deleted due to its age + maybeRequestNewCandidates chan struct{} // cap: 1. relayUpdated chan struct{} @@ -83,27 +82,37 @@ type relayFinder struct { cachedAddrsExpiry time.Time } -func newRelayFinder(host *basic.BasicHost, peerChan <-chan peer.AddrInfo, conf *config) *relayFinder { - r := &relayFinder{ - bootTime: time.Now(), - host: host, - conf: conf, - peerChan: peerChan, - candidates: make(map[peer.ID]*candidate), - candidateFound: make(chan struct{}, 1), - handleNewCandidateTrigger: make(chan struct{}, 1), - relays: make(map[peer.ID]*circuitv2.Reservation), - relayUpdated: make(chan struct{}, 1), +func newRelayFinder(host *basic.BasicHost, peerSource func(context.Context, int) <-chan peer.AddrInfo, conf *config) *relayFinder { + return &relayFinder{ + bootTime: conf.clock.Now(), + host: host, + conf: conf, + peerSource: peerSource, + candidates: make(map[peer.ID]*candidate), + backoff: make(map[peer.ID]time.Time), + candidateFound: make(chan struct{}, 1), + maybeConnectToRelayTrigger: make(chan struct{}, 1), + maybeRequestNewCandidates: make(chan struct{}, 1), + relays: make(map[peer.ID]*circuitv2.Reservation), + relayUpdated: make(chan struct{}, 1), } - return r } func (rf *relayFinder) background(ctx context.Context) { - rf.refCount.Add(1) - go func() { - defer rf.refCount.Done() - rf.findNodes(ctx) - }() + if rf.usesStaticRelay() { + rf.refCount.Add(1) + go func() { + defer rf.refCount.Done() + rf.handleStaticRelays(ctx) + }() + } else { + rf.refCount.Add(1) + go func() { + defer rf.refCount.Done() + rf.findNodes(ctx) + }() + } + rf.refCount.Add(1) go func() { defer rf.refCount.Done() @@ -117,12 +126,14 @@ func (rf *relayFinder) background(ctx context.Context) { } defer subConnectedness.Close() - bootDelayTimer := time.NewTimer(rf.conf.bootDelay) + bootDelayTimer := rf.conf.clock.Timer(rf.conf.bootDelay) defer bootDelayTimer.Stop() - refreshTicker := time.NewTicker(rsvpRefreshInterval) + refreshTicker := rf.conf.clock.Ticker(rsvpRefreshInterval) defer refreshTicker.Stop() - backoffTicker := time.NewTicker(rf.conf.backoff / 5) + backoffTicker := rf.conf.clock.Ticker(rf.conf.backoff / 5) defer backoffTicker.Stop() + oldCandidateTicker := rf.conf.clock.Ticker(rf.conf.maxCandidateAge / 5) + defer oldCandidateTicker.Stop() for { // when true, we need to identify push @@ -141,25 +152,42 @@ func (rf *relayFinder) background(ctx context.Context) { if rf.usingRelay(evt.Peer) { // we were disconnected from a relay log.Debugw("disconnected from relay", "id", evt.Peer) delete(rf.relays, evt.Peer) + rf.notifyMaybeConnectToRelay() + rf.notifyMaybeNeedNewCandidates() push = true } rf.relayMx.Unlock() case <-rf.candidateFound: - select { - case rf.handleNewCandidateTrigger <- struct{}{}: - default: - } + rf.notifyMaybeConnectToRelay() case <-bootDelayTimer.C: - select { - case rf.handleNewCandidateTrigger <- struct{}{}: - default: - } + rf.notifyMaybeConnectToRelay() case <-rf.relayUpdated: push = true case now := <-refreshTicker.C: push = rf.refreshReservations(ctx, now) case now := <-backoffTicker.C: - rf.checkForCandidatesOnBackoff(now) + rf.candidateMx.Lock() + for id, t := range rf.backoff { + if !t.Add(rf.conf.backoff).After(now) { + log.Debugw("removing backoff for node", "id", id) + delete(rf.backoff, id) + } + } + rf.candidateMx.Unlock() + case now := <-oldCandidateTicker.C: + var deleted bool + rf.candidateMx.Lock() + for id, cand := range rf.candidates { + if !cand.added.Add(rf.conf.maxCandidateAge).After(now) { + deleted = true + log.Debugw("deleting candidate due to age", "id", id) + delete(rf.candidates, id) + } + } + rf.candidateMx.Unlock() + if deleted { + rf.notifyMaybeNeedNewCandidates() + } case <-ctx.Done(): return } @@ -178,21 +206,63 @@ func (rf *relayFinder) background(ctx context.Context) { // It garbage collects old entries, so that nodes doesn't overflow. // This makes sure that as soon as we need to find relay candidates, we have them available. func (rf *relayFinder) findNodes(ctx context.Context) { + peerChan := rf.peerSource(ctx, rf.conf.maxCandidates) + var wg sync.WaitGroup + lastCallToPeerSource := rf.conf.clock.Now() + + timer := newTimer(rf.conf.clock) for { + rf.candidateMx.Lock() + numCandidates := len(rf.candidates) + rf.candidateMx.Unlock() + + if peerChan == nil { + now := rf.conf.clock.Now() + nextAllowedCallToPeerSource := lastCallToPeerSource.Add(rf.conf.minInterval).Sub(now) + if numCandidates < rf.conf.minCandidates { + log.Debugw("not enough candidates. Resetting timer", "num", numCandidates, "desired", rf.conf.minCandidates) + timer.Reset(nextAllowedCallToPeerSource) + } + } + select { - case pi := <-rf.peerChan: + case <-rf.maybeRequestNewCandidates: + continue + case now := <-timer.Chan(): + timer.SetRead() + if peerChan != nil { + // We're still reading peers from the peerChan. No need to query for more peers now. + continue + } + lastCallToPeerSource = now + peerChan = rf.peerSource(ctx, rf.conf.maxCandidates) + case pi, ok := <-peerChan: + if !ok { + wg.Wait() + peerChan = nil + continue + } log.Debugw("found node", "id", pi.ID) rf.candidateMx.Lock() numCandidates := len(rf.candidates) + backoffStart, isOnBackoff := rf.backoff[pi.ID] rf.candidateMx.Unlock() + if isOnBackoff { + log.Debugw("skipping node that we recently failed to obtain a reservation with", "id", pi.ID, "last attempt", rf.conf.clock.Since(backoffStart)) + continue + } if numCandidates >= rf.conf.maxCandidates { log.Debugw("skipping node. Already have enough candidates", "id", pi.ID, "num", numCandidates, "max", rf.conf.maxCandidates) continue } rf.refCount.Add(1) + wg.Add(1) go func() { defer rf.refCount.Done() - rf.handleNewNode(ctx, pi) + defer wg.Done() + if added := rf.handleNewNode(ctx, pi); added { + rf.notifyNewCandidate() + } }() case <-ctx.Done(): return @@ -200,6 +270,37 @@ func (rf *relayFinder) findNodes(ctx context.Context) { } } +func (rf *relayFinder) handleStaticRelays(ctx context.Context) { + sem := make(chan struct{}, 4) + var wg sync.WaitGroup + wg.Add(len(rf.conf.staticRelays)) + for _, pi := range rf.conf.staticRelays { + sem <- struct{}{} + go func(pi peer.AddrInfo) { + defer wg.Done() + defer func() { <-sem }() + rf.handleNewNode(ctx, pi) + }(pi) + } + wg.Wait() + log.Debug("processed all static relays") + rf.notifyNewCandidate() +} + +func (rf *relayFinder) notifyMaybeConnectToRelay() { + select { + case rf.maybeConnectToRelayTrigger <- struct{}{}: + default: + } +} + +func (rf *relayFinder) notifyMaybeNeedNewCandidates() { + select { + case rf.maybeRequestNewCandidates <- struct{}{}: + default: + } +} + func (rf *relayFinder) notifyNewCandidate() { select { case rf.candidateFound <- struct{}{}: @@ -211,12 +312,12 @@ func (rf *relayFinder) notifyNewCandidate() { // This method is only run on private nodes. // If a peer does, it is added to the candidates map. // Note that just supporting the protocol doesn't guarantee that we can also obtain a reservation. -func (rf *relayFinder) handleNewNode(ctx context.Context, pi peer.AddrInfo) { +func (rf *relayFinder) handleNewNode(ctx context.Context, pi peer.AddrInfo) (added bool) { rf.relayMx.Lock() relayInUse := rf.usingRelay(pi.ID) rf.relayMx.Unlock() if relayInUse { - return + return false } ctx, cancel := context.WithTimeout(ctx, 20*time.Second) @@ -224,18 +325,21 @@ func (rf *relayFinder) handleNewNode(ctx context.Context, pi peer.AddrInfo) { supportsV2, err := rf.tryNode(ctx, pi) if err != nil { log.Debugf("node %s not accepted as a candidate: %s", pi.ID, err) - return + return false } rf.candidateMx.Lock() if len(rf.candidates) > rf.conf.maxCandidates { rf.candidateMx.Unlock() - return + return false } log.Debugw("node supports relay protocol", "peer", pi.ID, "supports circuit v2", supportsV2) - rf.candidates[pi.ID] = &candidate{ai: pi, supportsRelayV2: supportsV2} + rf.candidates[pi.ID] = &candidate{ + added: rf.conf.clock.Now(), + ai: pi, + supportsRelayV2: supportsV2, + } rf.candidateMx.Unlock() - - rf.notifyNewCandidate() + return true } // tryNode checks if a peer actually supports either circuit v1 or circuit v2. @@ -311,28 +415,28 @@ func (rf *relayFinder) tryNode(ctx context.Context, pi peer.AddrInfo) (supportsR return false, nil } -// When a new node that could be a relay is found, we receive a notification on the handleNewCandidateTrigger chan. -// This function makes sure that we only run one instance of handleNewCandidate at once, and buffers -// exactly one more trigger event to run handleNewCandidate. +// When a new node that could be a relay is found, we receive a notification on the maybeConnectToRelayTrigger chan. +// This function makes sure that we only run one instance of maybeConnectToRelay at once, and buffers +// exactly one more trigger event to run maybeConnectToRelay. func (rf *relayFinder) handleNewCandidates(ctx context.Context) { sem := make(chan struct{}, 1) for { select { case <-ctx.Done(): return - case <-rf.handleNewCandidateTrigger: + case <-rf.maybeConnectToRelayTrigger: select { case <-ctx.Done(): return case sem <- struct{}{}: } - rf.handleNewCandidate(ctx) + rf.maybeConnectToRelay(ctx) <-sem } } } -func (rf *relayFinder) handleNewCandidate(ctx context.Context) { +func (rf *relayFinder) maybeConnectToRelay(ctx context.Context) { rf.relayMx.Lock() numRelays := len(rf.relays) rf.relayMx.Unlock() @@ -342,13 +446,7 @@ func (rf *relayFinder) handleNewCandidate(ctx context.Context) { } rf.candidateMx.Lock() - if len(rf.conf.staticRelays) != 0 { - // make sure we read all static relays before continuing - if len(rf.peerChan) > 0 && len(rf.candidates) < rf.conf.minCandidates && time.Since(rf.bootTime) < rf.conf.bootDelay { - rf.candidateMx.Unlock() - return - } - } else if len(rf.relays) == 0 && len(rf.candidates) < rf.conf.minCandidates && time.Since(rf.bootTime) < rf.conf.bootDelay { + if !rf.usesStaticRelay() && len(rf.relays) == 0 && len(rf.candidates) < rf.conf.minCandidates && rf.conf.clock.Since(rf.bootTime) < rf.conf.bootDelay { // During the startup phase, we don't want to connect to the first candidate that we find. // Instead, we wait until we've found at least minCandidates, and then select the best of those. // However, if that takes too long (longer than bootDelay), we still go ahead. @@ -370,11 +468,16 @@ func (rf *relayFinder) handleNewCandidate(ctx context.Context) { usingRelay := rf.usingRelay(id) rf.relayMx.Unlock() if usingRelay { + rf.candidateMx.Lock() + delete(rf.candidates, id) + rf.candidateMx.Unlock() + rf.notifyMaybeNeedNewCandidates() continue } rsvp, err := rf.connectToRelay(ctx, cand) if err != nil { log.Debugw("failed to connect to relay", "peer", id, "error", err) + rf.notifyMaybeNeedNewCandidates() continue } log.Debugw("adding new relay", "id", id) @@ -382,6 +485,7 @@ func (rf *relayFinder) handleNewCandidate(ctx context.Context) { rf.relays[id] = rsvp numRelays := len(rf.relays) rf.relayMx.Unlock() + rf.notifyMaybeNeedNewCandidates() rf.host.ConnManager().Protect(id, autorelayTag) // protect the connection @@ -389,6 +493,7 @@ func (rf *relayFinder) handleNewCandidate(ctx context.Context) { case rf.relayUpdated <- struct{}{}: default: } + if numRelays >= rf.conf.desiredRelays { break } @@ -401,7 +506,6 @@ func (rf *relayFinder) connectToRelay(ctx context.Context, cand *candidate) (*ci ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() - var failed bool var rsvp *circuitv2.Reservation // make sure we're still connected. @@ -413,68 +517,21 @@ func (rf *relayFinder) connectToRelay(ctx context.Context, cand *candidate) (*ci return nil, fmt.Errorf("failed to connect: %w", err) } } + + rf.candidateMx.Lock() + rf.backoff[id] = rf.conf.clock.Now() + rf.candidateMx.Unlock() var err error if cand.supportsRelayV2 { rsvp, err = circuitv2.Reserve(ctx, rf.host, cand.ai) if err != nil { - failed = true err = fmt.Errorf("failed to reserve slot: %w", err) } } rf.candidateMx.Lock() - defer rf.candidateMx.Unlock() - if failed { - cand.numAttempts++ - delete(rf.candidates, id) - // We failed to obtain a reservation for too many times. We give up. - if cand.numAttempts >= rf.conf.maxAttempts { - return nil, fmt.Errorf("failed to obtain a reservation too may times: %w", err) - } - rf.moveCandidateToBackoff(cand) - return nil, err - } - return rsvp, nil -} - -// must be called with mutex locked -func (rf *relayFinder) moveCandidateToBackoff(cand *candidate) { - if len(rf.candidatesOnBackoff) >= rf.conf.maxCandidates { - log.Debugw("already have enough candidates on backoff. Dropping.", "id", cand.ai.ID) - return - } - log.Debugw("moving candidate to backoff", "id", cand.ai.ID) - backoff := rf.conf.backoff * (1 << (cand.numAttempts - 1)) - // introduce a bit of jitter - backoff = (backoff * time.Duration(16+rand.Intn(8))) / time.Duration(20) - rf.candidatesOnBackoff = append(rf.candidatesOnBackoff, &candidateOnBackoff{ - candidate: *cand, - nextConnAttempt: time.Now().Add(backoff), - }) -} - -func (rf *relayFinder) checkForCandidatesOnBackoff(now time.Time) { - rf.candidateMx.Lock() - defer rf.candidateMx.Unlock() - - for _, cand := range rf.candidatesOnBackoff { - if cand.nextConnAttempt.After(now) { - break - } - if len(rf.candidates) >= rf.conf.maxCandidates { - // drop this candidate if we already have enough others - log.Debugw("cannot move backoff'ed candidate back. Already have enough candidates.", "id", cand.ai.ID) - } else { - log.Debugw("moving backoff'ed candidate back", "id", cand.ai.ID) - rf.candidates[cand.ai.ID] = &candidate{ - added: cand.added, - supportsRelayV2: cand.supportsRelayV2, - ai: cand.ai, - numAttempts: cand.numAttempts, - } - rf.notifyNewCandidate() - } - rf.candidatesOnBackoff = rf.candidatesOnBackoff[1:] - } + delete(rf.candidates, id) + rf.candidateMx.Unlock() + return rsvp, err } func (rf *relayFinder) refreshReservations(ctx context.Context, now time.Time) bool { @@ -528,7 +585,7 @@ func (rf *relayFinder) usingRelay(p peer.ID) bool { // selectCandidates returns an ordered slice of relay candidates. // Callers should attempt to obtain reservations with the candidates in this order. func (rf *relayFinder) selectCandidates() []*candidate { - var candidates []*candidate + candidates := make([]*candidate, 0, len(rf.candidates)) for _, cand := range rf.candidates { candidates = append(candidates, cand) } @@ -542,17 +599,17 @@ func (rf *relayFinder) selectCandidates() []*candidate { } // This function is computes the NATed relay addrs when our status is private: -// - The public addrs are removed from the address set. -// - The non-public addrs are included verbatim so that peers behind the same NAT/firewall -// can still dial us directly. -// - On top of those, we add the relay-specific addrs for the relays to which we are -// connected. For each non-private relay addr, we encapsulate the p2p-circuit addr -// through which we can be dialed. +// - The public addrs are removed from the address set. +// - The non-public addrs are included verbatim so that peers behind the same NAT/firewall +// can still dial us directly. +// - On top of those, we add the relay-specific addrs for the relays to which we are +// connected. For each non-private relay addr, we encapsulate the p2p-circuit addr +// through which we can be dialed. func (rf *relayFinder) relayAddrs(addrs []ma.Multiaddr) []ma.Multiaddr { rf.relayMx.Lock() defer rf.relayMx.Unlock() - if rf.cachedAddrs != nil && time.Now().Before(rf.cachedAddrsExpiry) { + if rf.cachedAddrs != nil && rf.conf.clock.Now().Before(rf.cachedAddrsExpiry) { return rf.cachedAddrs } @@ -577,11 +634,15 @@ func (rf *relayFinder) relayAddrs(addrs []ma.Multiaddr) []ma.Multiaddr { } rf.cachedAddrs = raddrs - rf.cachedAddrsExpiry = time.Now().Add(30 * time.Second) + rf.cachedAddrsExpiry = rf.conf.clock.Now().Add(30 * time.Second) return raddrs } +func (rf *relayFinder) usesStaticRelay() bool { + return len(rf.conf.staticRelays) > 0 +} + func (rf *relayFinder) Start() error { rf.ctxCancelMx.Lock() defer rf.ctxCancelMx.Unlock() diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/timer.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/timer.go new file mode 100644 index 000000000..b55445530 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/autorelay/timer.go @@ -0,0 +1,42 @@ +package autorelay + +import ( + "time" + + "github.com/benbjohnson/clock" +) + +type timer struct { + timer *clock.Timer + running bool + read bool +} + +func newTimer(cl clock.Clock) *timer { + t := cl.Timer(100 * time.Hour) // There's no way to initialize a stopped timer + t.Stop() + return &timer{timer: t} +} + +func (t *timer) Chan() <-chan time.Time { + return t.timer.C +} + +func (t *timer) Stop() { + if !t.running { + return + } + if !t.timer.Stop() && !t.read { + <-t.timer.C + } + t.read = false +} + +func (t *timer) SetRead() { + t.read = true +} + +func (t *timer) Reset(d time.Duration) { + t.Stop() + t.timer.Reset(d) +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go index 9073639ba..19fff7d2b 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/basic_host.go @@ -9,7 +9,17 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/core/record" "github.com/libp2p/go-libp2p/p2p/host/autonat" + "github.com/libp2p/go-libp2p/p2p/host/eventbus" "github.com/libp2p/go-libp2p/p2p/host/pstoremanager" "github.com/libp2p/go-libp2p/p2p/host/relaysvc" inat "github.com/libp2p/go-libp2p/p2p/net/nat" @@ -18,17 +28,6 @@ import ( "github.com/libp2p/go-libp2p/p2p/protocol/identify" "github.com/libp2p/go-libp2p/p2p/protocol/ping" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/protocol" - "github.com/libp2p/go-libp2p-core/record" - - "github.com/libp2p/go-eventbus" "github.com/libp2p/go-netroute" logging "github.com/ipfs/go-log/v2" @@ -39,10 +38,6 @@ import ( msmux "github.com/multiformats/go-multistream" ) -// The maximum number of address resolution steps we'll perform for a single -// peer (for all addresses). -const maxAddressResolution = 32 - // addrChangeTickrInterval is the interval between two address change ticks. var addrChangeTickrInterval = 5 * time.Second @@ -62,9 +57,9 @@ type AddrsFactory func([]ma.Multiaddr) []ma.Multiaddr // BasicHost is the basic implementation of the host.Host interface. This // particular host implementation: -// * uses a protocol muxer to mux per-protocol streams -// * uses an identity service to send + receive node information -// * uses a nat service to establish NAT port mappings +// - uses a protocol muxer to mux per-protocol streams +// - uses an identity service to send + receive node information +// - uses a nat service to establish NAT port mappings type BasicHost struct { ctx context.Context ctxCancel context.CancelFunc @@ -146,6 +141,9 @@ type HostOpts struct { // UserAgent sets the user-agent for the host. UserAgent string + // ProtocolVersion sets the protocol version for the host. + ProtocolVersion string + // DisableSignedPeerRecord disables the generation of Signed Peer Records on this host. DisableSignedPeerRecord bool @@ -227,9 +225,18 @@ func NewHost(n network.Network, opts *HostOpts) (*BasicHost, error) { // we can't set this as a default above because it depends on the *BasicHost. if h.disableSignedPeerRecord { - h.ids, err = identify.NewIDService(h, identify.UserAgent(opts.UserAgent), identify.DisableSignedPeerRecord()) + h.ids, err = identify.NewIDService( + h, + identify.UserAgent(opts.UserAgent), + identify.ProtocolVersion(opts.ProtocolVersion), + identify.DisableSignedPeerRecord(), + ) } else { - h.ids, err = identify.NewIDService(h, identify.UserAgent(opts.UserAgent)) + h.ids, err = identify.NewIDService( + h, + identify.UserAgent(opts.UserAgent), + identify.ProtocolVersion(opts.ProtocolVersion), + ) } if err != nil { return nil, fmt.Errorf("failed to create Identify service: %s", err) @@ -559,7 +566,9 @@ func (h *BasicHost) EventBus() event.Bus { // SetStreamHandler sets the protocol handler on the Host's Mux. // This is equivalent to: -// host.Mux().SetHandler(proto, handler) +// +// host.Mux().SetHandler(proto, handler) +// // (Threadsafe) func (h *BasicHost) SetStreamHandler(pid protocol.ID, handler network.StreamHandler) { h.Mux().AddHandler(string(pid), func(p string, rwc io.ReadWriteCloser) error { @@ -700,77 +709,9 @@ func (h *BasicHost) Connect(ctx context.Context, pi peer.AddrInfo) error { } } - resolved, err := h.resolveAddrs(ctx, h.Peerstore().PeerInfo(pi.ID)) - if err != nil { - return err - } - h.Peerstore().AddAddrs(pi.ID, resolved, peerstore.TempAddrTTL) - return h.dialPeer(ctx, pi.ID) } -func (h *BasicHost) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multiaddr, error) { - proto := ma.ProtocolWithCode(ma.P_P2P).Name - p2paddr, err := ma.NewMultiaddr("/" + proto + "/" + pi.ID.Pretty()) - if err != nil { - return nil, err - } - - resolveSteps := 0 - - // Recursively resolve all addrs. - // - // While the toResolve list is non-empty: - // * Pop an address off. - // * If the address is fully resolved, add it to the resolved list. - // * Otherwise, resolve it and add the results to the "to resolve" list. - toResolve := append(([]ma.Multiaddr)(nil), pi.Addrs...) - resolved := make([]ma.Multiaddr, 0, len(pi.Addrs)) - for len(toResolve) > 0 { - // pop the last addr off. - addr := toResolve[len(toResolve)-1] - toResolve = toResolve[:len(toResolve)-1] - - // if it's resolved, add it to the resolved list. - if !madns.Matches(addr) { - resolved = append(resolved, addr) - continue - } - - resolveSteps++ - - // We've resolved too many addresses. We can keep all the fully - // resolved addresses but we'll need to skip the rest. - if resolveSteps >= maxAddressResolution { - log.Warnf( - "peer %s asked us to resolve too many addresses: %s/%s", - pi.ID, - resolveSteps, - maxAddressResolution, - ) - continue - } - - // otherwise, resolve it - reqaddr := addr.Encapsulate(p2paddr) - resaddrs, err := h.maResolver.Resolve(ctx, reqaddr) - if err != nil { - log.Infof("error resolving %s: %s", reqaddr, err) - } - - // add the results to the toResolve list. - for _, res := range resaddrs { - pi, err := peer.AddrInfoFromP2pAddr(res) - if err != nil { - log.Infof("error parsing %s: %s", res, err) - } - toResolve = append(toResolve, pi.Addrs...) - } - } - - return resolved, nil -} - // dialPeer opens a connection to peer, and makes sure to identify // the connection once it has been opened. func (h *BasicHost) dialPeer(ctx context.Context, p peer.ID) error { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/natmgr.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/natmgr.go index 120b5d109..782c116d4 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/natmgr.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/natmgr.go @@ -8,10 +8,9 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/network" inat "github.com/libp2p/go-libp2p/p2p/net/nat" - "github.com/libp2p/go-libp2p-core/network" - ma "github.com/multiformats/go-multiaddr" ) @@ -34,9 +33,9 @@ func NewNATManager(net network.Network) NATManager { // natManager takes care of adding + removing port mappings to the nat. // Initialized with the host if it has a NATPortMap option enabled. // natManager receives signals from the network, and check on nat mappings: -// * natManager listens to the network and adds or closes port mappings -// as the network signals Listen() or ListenClose(). -// * closing the natManager closes the nat and its mappings. +// - natManager listens to the network and adds or closes port mappings +// as the network signals Listen() or ListenClose(). +// - closing the natManager closes the nat and its mappings. type natManager struct { net network.Network natMx sync.RWMutex diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/peer_connectedness.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/peer_connectedness.go index 5460498cc..bfc46ed8f 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/peer_connectedness.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/basic/peer_connectedness.go @@ -3,9 +3,9 @@ package basichost import ( "sync" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/blank.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/blank.go index 6f250a15c..16753eb0d 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/blank.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/blank.go @@ -6,16 +6,15 @@ import ( "fmt" "io" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/protocol" - "github.com/libp2p/go-libp2p-core/record" - - "github.com/libp2p/go-eventbus" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/core/record" + "github.com/libp2p/go-libp2p/p2p/host/eventbus" logging "github.com/ipfs/go-log/v2" @@ -159,9 +158,9 @@ func (bh *BlankHost) NewStream(ctx context.Context, p peer.ID, protos ...protoco return nil, err } - var protoStrs []string - for _, pid := range protos { - protoStrs = append(protoStrs, string(pid)) + protoStrs := make([]string, len(protos)) + for i, pid := range protos { + protoStrs[i] = string(pid) } selected, err := mstream.SelectOneOf(protoStrs, s) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/peer_connectedness.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/peer_connectedness.go index 670edc545..4f70540fc 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/peer_connectedness.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/blank/peer_connectedness.go @@ -3,9 +3,9 @@ package blankhost import ( "sync" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-eventbus/LICENSE-APACHE b/vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/LICENSE-APACHE similarity index 100% rename from vendor/github.com/libp2p/go-eventbus/LICENSE-APACHE rename to vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/LICENSE-APACHE diff --git a/vendor/github.com/libp2p/go-eventbus/LICENSE-MIT b/vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/LICENSE-MIT similarity index 100% rename from vendor/github.com/libp2p/go-eventbus/LICENSE-MIT rename to vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/LICENSE-MIT diff --git a/vendor/github.com/libp2p/go-eventbus/basic.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/basic.go similarity index 98% rename from vendor/github.com/libp2p/go-eventbus/basic.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/basic.go index 714153279..6ab6c410a 100644 --- a/vendor/github.com/libp2p/go-eventbus/basic.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/basic.go @@ -7,10 +7,10 @@ import ( "sync" "sync/atomic" - "github.com/libp2p/go-libp2p-core/event" + "github.com/libp2p/go-libp2p/core/event" ) -/////////////////////// +// ///////////////////// // BUS // basicBus is a type-based event delivery system @@ -267,13 +267,13 @@ func (b *basicBus) GetAllEventTypes() []reflect.Type { defer b.lk.RUnlock() types := make([]reflect.Type, 0, len(b.nodes)) - for t, _ := range b.nodes { + for t := range b.nodes { types = append(types, t) } return types } -/////////////////////// +// ///////////////////// // NODE type wildcardNode struct { diff --git a/vendor/github.com/libp2p/go-eventbus/opts.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/opts.go similarity index 90% rename from vendor/github.com/libp2p/go-eventbus/opts.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/opts.go index 921923500..a8eae6f2f 100644 --- a/vendor/github.com/libp2p/go-eventbus/opts.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/eventbus/opts.go @@ -19,7 +19,7 @@ type emitterSettings struct { makeStateful bool } -// Stateful is an Emitter option which makes makes the eventbus channel +// Stateful is an Emitter option which makes the eventbus channel // 'remember' last event sent, and when a new subscriber joins the // bus, the remembered event is immediately sent to the subscription // channel. diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/metrics.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/metrics.go similarity index 96% rename from vendor/github.com/libp2p/go-libp2p-peerstore/metrics.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/metrics.go index 87a941047..e05fda7d8 100644 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/metrics.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/metrics.go @@ -4,7 +4,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) // LatencyEWMASmoothing governs the decay of the EWMA (the speed diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/peerstore.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/peerstore.go similarity index 79% rename from vendor/github.com/libp2p/go-libp2p-peerstore/peerstore.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/peerstore.go index 9f5eda8f4..45c22c362 100644 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/peerstore.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/peerstore.go @@ -1,8 +1,8 @@ package peerstore import ( - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) func PeerInfos(ps pstore.Peerstore, peers peer.IDSlice) []peer.AddrInfo { diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/addr_book.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/addr_book.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/addr_book.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/addr_book.go index 7e6a67fa0..28aa6d4d3 100644 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/addr_book.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/addr_book.go @@ -7,9 +7,9 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/record" logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" @@ -183,7 +183,7 @@ func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du // ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in // a record.Envelope), which will expire after the given TTL. -// See https://godoc.org/github.com/libp2p/go-libp2p-core/peerstore#CertifiedAddrBook for more details. +// See https://godoc.org/github.com/libp2p/go-libp2p/core/peerstore#CertifiedAddrBook for more details. func (mab *memoryAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, ttl time.Duration) (bool, error) { r, err := recordEnvelope.Record() if err != nil { diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/keybook.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/keybook.go similarity index 92% rename from vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/keybook.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/keybook.go index 387a57361..f995a0879 100644 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/keybook.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/keybook.go @@ -4,10 +4,9 @@ import ( "errors" "sync" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - - pstore "github.com/libp2p/go-libp2p-core/peerstore" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) type memoryKeyBook struct { diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/metadata.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/metadata.go similarity index 91% rename from vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/metadata.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/metadata.go index 0fd41c07d..305c74171 100644 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/metadata.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/metadata.go @@ -3,8 +3,8 @@ package pstoremem import ( "sync" - "github.com/libp2p/go-libp2p-core/peer" - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) type memoryPeerMetadata struct { diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/peerstore.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/peerstore.go similarity index 94% rename from vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/peerstore.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/peerstore.go index ce34dc851..ec403f84c 100644 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/peerstore.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/peerstore.go @@ -4,10 +4,9 @@ import ( "fmt" "io" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - - pstore "github.com/libp2p/go-libp2p-peerstore" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + pstore "github.com/libp2p/go-libp2p/p2p/host/peerstore" ) type pstoremem struct { diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/protobook.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/protobook.go similarity index 97% rename from vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/protobook.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/protobook.go index b2cf73e1c..7a955c076 100644 --- a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/protobook.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/protobook.go @@ -4,9 +4,8 @@ import ( "errors" "sync" - "github.com/libp2p/go-libp2p-core/peer" - - pstore "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/peer" + pstore "github.com/libp2p/go-libp2p/core/peerstore" ) type protoSegment struct { diff --git a/vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/sorting.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/sorting.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-peerstore/pstoremem/sorting.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/peerstore/pstoremem/sorting.go diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/pstoremanager/pstoremanager.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/pstoremanager/pstoremanager.go index 311ca0c98..f8382c709 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/pstoremanager/pstoremanager.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/pstoremanager/pstoremanager.go @@ -5,10 +5,10 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" logging "github.com/ipfs/go-log/v2" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/relaysvc/relay.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/relaysvc/relay.go index d1928b334..a36e20e00 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/relaysvc/relay.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/relaysvc/relay.go @@ -6,9 +6,9 @@ import ( relayv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" ) type RelayManager struct { diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/README.md b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/README.md similarity index 58% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/README.md rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/README.md index 7e3972b8b..96edd1d0c 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/README.md +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/README.md @@ -7,27 +7,49 @@ The implementation is based on the concept of Resource Management Scopes, whereby resource usage is constrained by a DAG of scopes, accounting for multiple levels of resource constraints. -## Design Considerations +The Resource Manager doesn't prioritize resource requests at all, it simply +checks if the resource being requested is currently below the defined limits and +returns an error if the limit is reached. It has no notion of honest vs bad peers. -- The Resource Manager must account for basic resource usage at all - levels of the stack, from the internals to application components - that use the network facilities of libp2p. -- Basic resources include memory, streams, connections, and file - descriptors. These account for both space and time used by - the stack, as each resource has a direct effect on the system - availability and performance. -- The design must support seamless integration for user applications, - which should reap the benefits of resource management without any - changes. That is, existing applications should be oblivious of the - resource manager and transparently obtain limits which protect it - from resource exhaustion and OOM conditions. -- At the same time, the design must support opt-in resource usage - accounting for applications who want to explicitly utilize the - facilities of the system to inform about and constrain their own - resource usage. -- The design must allow the user to set its own limits, which can be - static (fixed) or dynamic. +The Resource Manager does have a special notion of [allowlisted](#allowlisting-multiaddrs-to-mitigate-eclipse-attacks) multiaddrs that +have their own limits if the normal system limits are reached. +## Usage + +The Resource Manager is intended to be used with go-libp2p. go-libp2p sets up a +resource manager with the default autoscaled limits if none is provided, but if +you want to configure things or if you want to enable metrics you'll use the +resource manager like so: + +```go +// Start with the default scaling limits. +scalingLimits := rcmgr.DefaultLimits + +// Add limits around included libp2p protocols +libp2p.SetDefaultServiceLimits(&scalingLimits) + +// Turn the scaling limits into a static set of limits using `.AutoScale`. This +// scales the limits proportional to your system memory. +limits := scalingLimits.AutoScale() + +// The resource manager expects a limiter, se we create one from our limits. +limiter := rcmgr.NewFixedLimiter(limits) + +// (Optional if you want metrics) Construct the OpenCensus metrics reporter. +str, err := rcmgrObs.NewStatsTraceReporter() +if err != nil { + panic(err) +} + +// Initialize the resource manager +rm, err := rcmgr.NewResourceManager(limiter, rcmgr.WithTraceReporter(str)) +if err != nil { + panic(err) +} + +// Create a libp2p host +host, err := libp2p.New(libp2p.ResourceManager(rm)) +``` ## Basic Resources @@ -50,13 +72,13 @@ File descriptors are an important resource that uses memory (and computational time) at the system level. They are also a scarce resource, as typically (unless the user explicitly intervenes) they are constrained by the system. Exhaustion of file descriptors may -render the application incapable of operating (e.g. because it is -unable to open a file), most importantly for libp2p because most +render the application incapable of operating (e.g., because it is +unable to open a file). This is important for libp2p because most operating systems represent sockets as file descriptors. ### Connections -Connections are a higher level concept endemic to libp2p; in order to +Connections are a higher-level concept endemic to libp2p; in order to communicate with another peer, a connection must first be established. Connections are an important resource in libp2p, as they consume memory, goroutines, and possibly file descriptors. @@ -137,6 +159,22 @@ The transient scope effectively represents a DMZ (DeMilitarized Zone), where resource usage can be accounted for connections and streams that are not fully established. +### The Allowlist System Scope + +Same as the normal system scope above, but is used if the normal system scope is +already at its limits and the resource is from an allowlisted peer. See +[Allowlisting multiaddrs to mitigate eclipse +attacks](#allowlisting-multiaddrs-to-mitigate-eclipse-attacks) see for more +information. + +### The Allowlist Transient Scope + +Same as the normal transient scope above, but is used if the normal transient +scope is already at its limits and the resource is from an allowlisted peer. See +[Allowlisting multiaddrs to mitigate eclipse +attacks](#allowlisting-multiaddrs-to-mitigate-eclipse-attacks) see for more +information. + ### Service Scopes The system is typically organized across services, which may be @@ -207,7 +245,7 @@ scope. ### User Transaction Scopes User transaction scopes can be created as a child of any extant -resource scope, and provide the prgrammer with a delimited scope for +resource scope, and provide the programmer with a delimited scope for easy resource accounting. Transactions may form a tree that is rooted to some canonical scope in the scope DAG. @@ -220,16 +258,231 @@ uses a buffer. ## Limits Each resource scope has an associated limit object, which designates -limits for all basic resources. The limit is checked every time some +limits for all [basic resources](#basic-resources). The limit is checked every time some resource is reserved and provides the system with an opportunity to constrain resource usage. -There are separate limits for each class of scope, allowing us for +There are separate limits for each class of scope, allowing for multiresolution and aggregate resource accounting. As such, we have limits for the system and transient scopes, default and specific limits for services, protocols, and peers, and limits for connections and streams. +### Scaling Limits + +When building software that is supposed to run on many different kind of machines, +with various memory and CPU configurations, it is desireable to have limits that +scale with the size of the machine. + +This is done using the `ScalingLimitConfig`. For every scope, this configuration +struct defines the absolutely bare minimum limits, and an (optional) increase of +these limits, which will be applied on nodes that have sufficient memory. + +A `ScalingLimitConfig` can be converted into a `LimitConfig` (which can then be +used to initialize a fixed limiter with `NewFixedLimiter`) by calling the `Scale` method. +The `Scale` method takes two parameters: the amount of memory and the number of file +descriptors that an application is willing to dedicate to libp2p. + +These amounts will differ between use cases. A blockchain node running on a dedicated +server might have a lot of memory, and dedicate 1/4 of that memory to libp2p. On the +other end of the spectrum, a desktop companion application running as a background +task on a consumer laptop will probably dedicate significantly less than 1/4 of its system +memory to libp2p. + +For convenience, the `ScalingLimitConfig` also provides an `AutoScale` method, +which determines the amount of memory and file descriptors available on the +system, and dedicates up to 1/8 of the memory and 1/2 of the file descriptors to +libp2p. + +For example, one might set: +```go +var scalingLimits = ScalingLimitConfig{ + SystemBaseLimit: BaseLimit{ + ConnsInbound: 64, + ConnsOutbound: 128, + Conns: 128, + StreamsInbound: 512, + StreamsOutbound: 1024, + Streams: 1024, + Memory: 128 << 20, + FD: 256, + }, + SystemLimitIncrease: BaseLimitIncrease{ + ConnsInbound: 32, + ConnsOutbound: 64, + Conns: 64, + StreamsInbound: 256, + StreamsOutbound: 512, + Streams: 512, + Memory: 256 << 20, + FDFraction: 1, + }, +} +``` + +The base limit (`SystemBaseLimit`) here is the minimum configuration that any +node will have, no matter how little memory it possesses. For every GB of memory +passed into the `Scale` method, an increase of (`SystemLimitIncrease`) is added. + +For Example, calling `Scale` with 4 GB of memory will result in a limit of 384 for +`Conns` (128 + 4*64). + +The `FDFraction` defines how many of the file descriptors are allocated to this +scope. In the example above, when called with a file descriptor value of 1000, +this would result in a limit of 1000 (1000 * 1) file descriptors for the system +scope. See `TestReadmeExample` in `limit_test.go`. + +Note that we only showed the configuration for the system scope here, equivalent +configuration options apply to all other scopes as well. + +### Default limits + +By default the resource manager ships with some reasonable scaling limits and +makes a reasonable guess at how much system memory you want to dedicate to the +go-libp2p process. For the default definitions see [`DefaultLimits` and +`ScalingLimitConfig.AutoScale()`](./limit_defaults.go). + +### Tweaking Defaults + +If the defaults seem mostly okay, but you want to adjust one facet you can +simply copy the default struct object and update the field you want to change. You can +apply changes to a `BaseLimit`, `BaseLimitIncrease`, and `LimitConfig` with +`.Apply`. + +Example +``` +// An example on how to tweak the default limits +tweakedDefaults := DefaultLimits +tweakedDefaults.ProtocolBaseLimit.Streams = 1024 +tweakedDefaults.ProtocolBaseLimit.StreamsInbound = 512 +tweakedDefaults.ProtocolBaseLimit.StreamsOutbound = 512 +``` + +### How to tune your limits + +Once you've set your limits and monitoring (see [Monitoring](#monitoring) below) +you can now tune your limits better. The `rcmgr_blocked_resources` metric will +tell you what was blocked and for what scope. If you see a steady stream of +these blocked requests it means your resource limits are too low for your usage. +If you see a rare sudden spike, this is okay and it means the resource manager +protected you from some anomaly. + +### How to disable limits + +Sometimes disabling all limits is useful when you want to see how much +resources you use during normal operation. You can then use this information to +define your initial limits. Disable the limits by using `InfiniteLimits`. + +### Debug "resource limit exceeded" errors + +These errors occur whenever a limit is hit. For example, you'll get this error if +you are at your limit for the number of streams you can have, and you try to +open one more. + +Example Log: +``` +2022-08-12T15:49:35.459-0700 DEBUG rcmgr go-libp2p-resource-manager@v0.5.3/scope.go:541 blocked connection from constraining edge {"scope": "conn-19667", "edge": "system", "direction": "Inbound", "usefd": false, "current": 100, "attempted": 1, "limit": 100, "stat": {"NumStreamsInbound":28,"NumStreamsOutbound":66,"NumConnsInbound":37,"NumConnsOutbound":63,"NumFD":33,"Memory":8687616}, "error": "system: cannot reserve connection: resource limit exceeded"} +``` + +The log line above is an example log line that gets emitted if you enable debug +logging in the resource manager. You can do this by setting the environment +variable `GOLOG_LOG_LEVEL="rcmgr=info"`. By default only the error is +returned to the caller, and nothing is logged by the resource manager itself. + +The log line message (and returned error) will tell you which resource limit was +hit (connection in the log above) and what blocked it (in this case it was the +system scope that blocked it). The log will also include some more information +about the current usage of the resources. In the example log above, there is a +limit of 100 connections, and you can see that we have 37 inbound connections +and 63 outbound connections. We've reached the limit and the resource manager +will block any further connections. + +The next step in debugging is seeing if this is a recurring problem or just a +transient error. If it's a transient error it's okay to ignore it since the +resource manager was doing its job in keeping resource usage under the limit. If +it's recurring then you should understand what's causing you to hit these limits +and either refactor your application or raise the limits. + +To check if it's a recurring problem you can count the number of times you've +seen the `"resource limit exceeded"` error over time. You can also check the +`rcmgr_blocked_resources` metric to see how many times the resource manager has +blocked a resource over time. + +![Example graph of blocked resources over time](https://bafkreibul6qipnax5s42abv3jc6bolhd7pju3zbl4rcvdaklmk52f6cznu.ipfs.w3s.link/) + +If the resource is blocked by a protocol-level scope, take a look at the various +resource usages in the metrics. For example, if you run into a new stream being blocked, +you can check the +`rcmgr_streams` metric and the "Streams by protocol" graph in the Grafana +dashboard (assuming you've set that up or something similar – see +[Monitoring](#monitoring)) to understand the usage pattern of that specific +protocol. This can help answer questions such as: "Am I constantly around my +limit?", "Does it make sense to raise my limit?", "Are there any patterns around +hitting this limit?", and "should I refactor my protocol implementation?" + +## Monitoring + +Once you have limits set, you'll want to monitor to see if you're running into +your limits often. This could be a sign that you need to raise your limits +(your process is more intensive than you originally thought) or that you need +to fix something in your application (surely you don't need over 1000 streams?). + +There are OpenCensus metrics that can be hooked up to the resource manager. See +`obs/stats_test.go` for an example on how to enable this, and `DefaultViews` in +`stats.go` for recommended views. These metrics can be hooked up to Prometheus +or any other OpenCensus supported platform. + +There is also an included Grafana dashboard to help kickstart your +observability into the resource manager. Find more information about it at +[here](./obs/grafana-dashboards/README.md). + +## Allowlisting multiaddrs to mitigate eclipse attacks + +If you have a set of trusted peers and IP addresses, you can use the resource +manager's [Allowlist](./docs/allowlist.md) to protect yourself from eclipse +attacks. The set of peers in the allowlist will have their own limits in case +the normal limits are reached. This means you will always be able to connect to +these trusted peers even if you've already reached your system limits. + +Look at `WithAllowlistedMultiaddrs` and its example in the GoDoc to learn more. + +## ConnManager vs Resource Manager + +go-libp2p already includes a [connection +manager](https://pkg.go.dev/github.com/libp2p/go-libp2p/core/connmgr#ConnManager), +so what's the difference between the `ConnManager` and the `ResourceManager`? + +ConnManager: +1. Configured with a low and high watermark number of connections. +2. Attempts to maintain the number of connections between the low and high + markers. +3. Connections can be given metadata and weight (e.g. a hole punched + connection is more valuable than a connection to a publicly addressable + endpoint since it took more effort to make the hole punched connection). +4. The ConnManager will trim connections once the high watermark is reached. and + trim down to the low watermark. +5. Won't block adding another connection above the high watermark, but will + trigger the trim mentioned above. +6. Can trim and prioritize connections with custom logic. +7. No concept of scopes (like the resource manager). + +Resource Manager: +1. Configured with limits on the number of outgoing and incoming connections at + different [resource scopes](#resource-scopes). +2. Will block adding any more connections if any of the scope-specific limits would be exceeded. + +The natural question when comparing these two managers is "how do the watermarks +and limits interact with each other?". The short answer is that they don't know +about each other. This can lead to some surprising subtleties, such as the +trimming never happening because the resource manager's limit is lower than the +high watermark. This is confusing, and we'd like to fix it. The issue is +captured in [go-libp2p#1640](https://github.com/libp2p/go-libp2p/issues/1640). + +When configuring the resource manager and connection manager, you should set the +limits in the resource manager as your hard limits that you would never want to +go over, and set the low/high watermarks as the range at which your application +works best. + ## Examples Here we consider some concrete examples that can ellucidate the abstract @@ -281,78 +534,6 @@ aid understanding of applicable limits. Note that the (wrapped) error implements `net.Error` and is marked as temporary, so that the programmer can handle by backoff retry. -## Usage - -This package provides a limiter implementation that applies fixed limits: -```go -limiter := NewFixedLimiter(limits) -``` -The `limits` allows fine-grained control of resource usage on all scopes. - -### Scaling Limits - -When building software that is supposed to run on many different kind of machines, -with various memory and CPU configurations, it is desireable to have limits that -scale with the size of the machine. - -This is done using the `ScalingLimitConfig`. For every scope, this configuration -struct defines the absolutely bare minimum limits, and an (optional) increase of -these limits, which will be applied on nodes that have sufficient memory. - -A `ScalingLimitConfig` can be converted into a `LimitConfig` (which can then be -used to initialize a fixed limiter as shown above) by calling the `Scale` method. -The `Scale` method takes two parameters: the amount of memory and the number of file -descriptors that an application is willing to dedicate to libp2p. - -These amounts will differ between use cases: A blockchain node running on a dedicated -server might have a lot of memory, and dedicate 1/4 of that memory to libp2p. On the -other end of the spectrum, a desktop companion application running as a background -task on a consumer laptop will probably dedicate significantly less than 1/4 of its system -memory to libp2p. - -For convenience, the `ScalingLimitConfig` also provides an `AutoScale` method, -which determines the amount of memory and file descriptors available on the -system, and dedicates up to 1/8 of the memory and 1/2 of the file descriptors to libp2p. - -For example, one might set: -```go -var scalingLimits = ScalingLimitConfig{ - SystemBaseLimit: BaseLimit{ - ConnsInbound: 64, - ConnsOutbound: 128, - Conns: 128, - StreamsInbound: 512, - StreamsOutbound: 1024, - Streams: 1024, - Memory: 128 << 20, - FD: 256, - }, - SystemLimitIncrease: BaseLimitIncrease{ - ConnsInbound: 32, - ConnsOutbound: 64, - Conns: 64, - StreamsInbound: 256, - StreamsOutbound: 512, - Streams: 512, - Memory: 256 << 20, - FDFraction: 1, - }, -} -``` - -The base limit (`SystemBaseLimit`) here is the minimum configuration that any -node will have, no matter how little memory it possesses. For every GB of memory -passed into the `Scale` method, an increase of (`SystemLimitIncrease`) is added. - -For Example, calling `Scale` with 4 GB of memory will result in a limit of 384 for -`Conns` (128 + 4*64). - -The `FDFraction` defines how many of the file descriptors are allocated to this -scope. In the example above, when called with a file descriptor value of 1000, -this would result in a limit of 1256 file descriptors for the system scope. - -Note that we only showed the configuration for the system scope here, equivalent -configuration options apply to all other scopes as well. ## Implementation Notes @@ -366,3 +547,24 @@ configuration options apply to all other scopes as well. pointer to a generic resource scope. - Peer and Protocol scopes, which may be created in response to network events, are periodically garbage collected. + +## Design Considerations + +- The Resource Manager must account for basic resource usage at all + levels of the stack, from the internals to application components + that use the network facilities of libp2p. +- Basic resources include memory, streams, connections, and file + descriptors. These account for both space and time used by + the stack, as each resource has a direct effect on the system + availability and performance. +- The design must support seamless integration for user applications, + which should reap the benefits of resource management without any + changes. That is, existing applications should be oblivious of the + resource manager and transparently obtain limits which protects it + from resource exhaustion and OOM conditions. +- At the same time, the design must support opt-in resource usage + accounting for applications that want to explicitly utilize the + facilities of the system to inform about and constrain their own + resource usage. +- The design must allow the user to set their own limits, which can be + static (fixed) or dynamic. diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/allowlist.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/allowlist.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/allowlist.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/allowlist.go index fd72af07c..d2bdb8693 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/allowlist.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/allowlist.go @@ -7,7 +7,8 @@ import ( "net" "sync" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/error.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/error.go similarity index 98% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/error.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/error.go index 1ccc86f99..4b02672b8 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/error.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/error.go @@ -3,7 +3,7 @@ package rcmgr import ( "errors" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) type errStreamOrConnLimitExceeded struct { diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/extapi.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/extapi.go similarity index 96% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/extapi.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/extapi.go index 92605c82b..302678e19 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/extapi.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/extapi.go @@ -5,9 +5,9 @@ import ( "sort" "strings" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // ResourceScopeLimiter is a trait interface that allows you to access scope limits. diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/limit.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit.go similarity index 87% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/limit.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit.go index b1c7d6371..7d0823b1e 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/limit.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit.go @@ -1,12 +1,21 @@ +/* +Package rcmgr is the resource manager for go-libp2p. This allows you to track +resources being used throughout your go-libp2p process. As well as making sure +that the process doesn't use more resources than what you define as your +limits. The resource manager only knows about things it is told about, so it's +the responsibility of the user of this library (either go-libp2p or a go-libp2p +user) to make sure they check with the resource manager before actually +allocating the resource. +*/ package rcmgr import ( "encoding/json" "io" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // Limit is an object that specifies basic resource limits. @@ -117,7 +126,7 @@ func (l *BaseLimit) Apply(l2 BaseLimit) { } } -// BaseLimitIncrease is the increase per GB of system memory. +// BaseLimitIncrease is the increase per GiB of allowed memory. type BaseLimitIncrease struct { Streams int StreamsInbound int @@ -125,8 +134,10 @@ type BaseLimitIncrease struct { Conns int ConnsInbound int ConnsOutbound int - Memory int64 - FDFraction float64 + // Memory is in bytes. Values over 1>>30 (1GiB) don't make sense. + Memory int64 + // FDFraction is expected to be >= 0 and <= 1. + FDFraction float64 } // Apply overwrites all zero-valued limits with the values of l2 diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/limit_config_test.json b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit_config_test.json similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/limit_config_test.json rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit_config_test.json diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/limit_defaults.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit_defaults.go similarity index 89% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/limit_defaults.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit_defaults.go index bb10b7c26..dde3e7b7a 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/limit_defaults.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/limit_defaults.go @@ -4,8 +4,8 @@ import ( "encoding/json" "math" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" "github.com/pbnjay/memory" ) @@ -141,7 +141,7 @@ func (cfg *LimitConfig) MarshalJSON() ([]byte, error) { // we want to marshal the encoded peer id encodedPeerMap := make(map[string]BaseLimit, len(cfg.Peer)) for p, v := range cfg.Peer { - encodedPeerMap[peer.Encode(p)] = v + encodedPeerMap[p.String()] = v } type Alias LimitConfig @@ -255,55 +255,50 @@ func (cfg *LimitConfig) Apply(c LimitConfig) { // Scale scales up a limit configuration. // memory is the amount of memory that the stack is allowed to consume, -// for a full it's recommended to use 1/8 of the installed system memory. +// for a dedicated node it's recommended to use 1/8 of the installed system memory. // If memory is smaller than 128 MB, the base configuration will be used. -// func (cfg *ScalingLimitConfig) Scale(memory int64, numFD int) LimitConfig { - var scaleFactor int - if memory > 128<<20 { - scaleFactor = int((memory - 128<<20) >> 20) - } lc := LimitConfig{ - System: scale(cfg.SystemBaseLimit, cfg.SystemLimitIncrease, scaleFactor, numFD), - Transient: scale(cfg.TransientBaseLimit, cfg.TransientLimitIncrease, scaleFactor, numFD), - AllowlistedSystem: scale(cfg.AllowlistedSystemBaseLimit, cfg.AllowlistedSystemLimitIncrease, scaleFactor, numFD), - AllowlistedTransient: scale(cfg.AllowlistedTransientBaseLimit, cfg.AllowlistedTransientLimitIncrease, scaleFactor, numFD), - ServiceDefault: scale(cfg.ServiceBaseLimit, cfg.ServiceLimitIncrease, scaleFactor, numFD), - ServicePeerDefault: scale(cfg.ServicePeerBaseLimit, cfg.ServicePeerLimitIncrease, scaleFactor, numFD), - ProtocolDefault: scale(cfg.ProtocolBaseLimit, cfg.ProtocolLimitIncrease, scaleFactor, numFD), - ProtocolPeerDefault: scale(cfg.ProtocolPeerBaseLimit, cfg.ProtocolPeerLimitIncrease, scaleFactor, numFD), - PeerDefault: scale(cfg.PeerBaseLimit, cfg.PeerLimitIncrease, scaleFactor, numFD), - Conn: scale(cfg.ConnBaseLimit, cfg.ConnLimitIncrease, scaleFactor, numFD), - Stream: scale(cfg.StreamBaseLimit, cfg.ConnLimitIncrease, scaleFactor, numFD), + System: scale(cfg.SystemBaseLimit, cfg.SystemLimitIncrease, memory, numFD), + Transient: scale(cfg.TransientBaseLimit, cfg.TransientLimitIncrease, memory, numFD), + AllowlistedSystem: scale(cfg.AllowlistedSystemBaseLimit, cfg.AllowlistedSystemLimitIncrease, memory, numFD), + AllowlistedTransient: scale(cfg.AllowlistedTransientBaseLimit, cfg.AllowlistedTransientLimitIncrease, memory, numFD), + ServiceDefault: scale(cfg.ServiceBaseLimit, cfg.ServiceLimitIncrease, memory, numFD), + ServicePeerDefault: scale(cfg.ServicePeerBaseLimit, cfg.ServicePeerLimitIncrease, memory, numFD), + ProtocolDefault: scale(cfg.ProtocolBaseLimit, cfg.ProtocolLimitIncrease, memory, numFD), + ProtocolPeerDefault: scale(cfg.ProtocolPeerBaseLimit, cfg.ProtocolPeerLimitIncrease, memory, numFD), + PeerDefault: scale(cfg.PeerBaseLimit, cfg.PeerLimitIncrease, memory, numFD), + Conn: scale(cfg.ConnBaseLimit, cfg.ConnLimitIncrease, memory, numFD), + Stream: scale(cfg.StreamBaseLimit, cfg.ConnLimitIncrease, memory, numFD), } if cfg.ServiceLimits != nil { lc.Service = make(map[string]BaseLimit) for svc, l := range cfg.ServiceLimits { - lc.Service[svc] = scale(l.BaseLimit, l.BaseLimitIncrease, scaleFactor, numFD) + lc.Service[svc] = scale(l.BaseLimit, l.BaseLimitIncrease, memory, numFD) } } if cfg.ProtocolLimits != nil { lc.Protocol = make(map[protocol.ID]BaseLimit) for proto, l := range cfg.ProtocolLimits { - lc.Protocol[proto] = scale(l.BaseLimit, l.BaseLimitIncrease, scaleFactor, numFD) + lc.Protocol[proto] = scale(l.BaseLimit, l.BaseLimitIncrease, memory, numFD) } } if cfg.PeerLimits != nil { lc.Peer = make(map[peer.ID]BaseLimit) for p, l := range cfg.PeerLimits { - lc.Peer[p] = scale(l.BaseLimit, l.BaseLimitIncrease, scaleFactor, numFD) + lc.Peer[p] = scale(l.BaseLimit, l.BaseLimitIncrease, memory, numFD) } } if cfg.ServicePeerLimits != nil { lc.ServicePeer = make(map[string]BaseLimit) for svc, l := range cfg.ServicePeerLimits { - lc.ServicePeer[svc] = scale(l.BaseLimit, l.BaseLimitIncrease, scaleFactor, numFD) + lc.ServicePeer[svc] = scale(l.BaseLimit, l.BaseLimitIncrease, memory, numFD) } } if cfg.ProtocolPeerLimits != nil { lc.ProtocolPeer = make(map[protocol.ID]BaseLimit) for p, l := range cfg.ProtocolPeerLimits { - lc.ProtocolPeer[p] = scale(l.BaseLimit, l.BaseLimitIncrease, scaleFactor, numFD) + lc.ProtocolPeer[p] = scale(l.BaseLimit, l.BaseLimitIncrease, memory, numFD) } } return lc @@ -316,20 +311,30 @@ func (cfg *ScalingLimitConfig) AutoScale() LimitConfig { ) } -// factor is the number of MBs above the minimum (128 MB) -func scale(base BaseLimit, inc BaseLimitIncrease, factor int, numFD int) BaseLimit { +func scale(base BaseLimit, inc BaseLimitIncrease, memory int64, numFD int) BaseLimit { + // mebibytesAvailable represents how many MiBs we're allowed to use. Used to + // scale the limits. If this is below 128MiB we set it to 0 to just use the + // base amounts. + var mebibytesAvailable int + if memory > 128<<20 { + mebibytesAvailable = int((memory) >> 20) + } l := BaseLimit{ - StreamsInbound: base.StreamsInbound + (inc.StreamsInbound*factor)>>10, - StreamsOutbound: base.StreamsOutbound + (inc.StreamsOutbound*factor)>>10, - Streams: base.Streams + (inc.Streams*factor)>>10, - ConnsInbound: base.ConnsInbound + (inc.ConnsInbound*factor)>>10, - ConnsOutbound: base.ConnsOutbound + (inc.ConnsOutbound*factor)>>10, - Conns: base.Conns + (inc.Conns*factor)>>10, - Memory: base.Memory + (inc.Memory*int64(factor))>>10, + StreamsInbound: base.StreamsInbound + (inc.StreamsInbound*mebibytesAvailable)>>10, + StreamsOutbound: base.StreamsOutbound + (inc.StreamsOutbound*mebibytesAvailable)>>10, + Streams: base.Streams + (inc.Streams*mebibytesAvailable)>>10, + ConnsInbound: base.ConnsInbound + (inc.ConnsInbound*mebibytesAvailable)>>10, + ConnsOutbound: base.ConnsOutbound + (inc.ConnsOutbound*mebibytesAvailable)>>10, + Conns: base.Conns + (inc.Conns*mebibytesAvailable)>>10, + Memory: base.Memory + (inc.Memory*int64(mebibytesAvailable))>>10, FD: base.FD, } if inc.FDFraction > 0 && numFD > 0 { l.FD = int(inc.FDFraction * float64(numFD)) + if l.FD < base.FD { + // Use at least the base amount + l.FD = base.FD + } } return l } @@ -509,7 +514,7 @@ var DefaultLimits = ScalingLimitConfig{ ConnsOutbound: 1, Conns: 1, FD: 1, - Memory: 1 << 20, + Memory: 32 << 20, }, StreamBaseLimit: BaseLimit{ diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/metrics.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/metrics.go similarity index 96% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/metrics.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/metrics.go index a875415a2..2f9e6b31b 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/metrics.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/metrics.go @@ -1,9 +1,9 @@ package rcmgr import ( - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" ) // MetricsReporter is an interface for collecting metrics from resource manager actions diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/rcmgr.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/rcmgr.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/rcmgr.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/rcmgr.go index b2cd18cc7..03d100a63 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/rcmgr.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/rcmgr.go @@ -7,12 +7,12 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - "github.com/multiformats/go-multiaddr" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" logging "github.com/ipfs/go-log/v2" + "github.com/multiformats/go-multiaddr" ) var log = logging.Logger("rcmgr") diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/scope.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/scope.go similarity index 93% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/scope.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/scope.go index 219052724..2a83c6950 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/scope.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/scope.go @@ -2,10 +2,12 @@ package rcmgr import ( "fmt" + "math" + "math/big" "strings" "sync" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) // resources tracks the current state of resource consumption @@ -79,14 +81,55 @@ func IsSpan(name string) bool { return strings.Contains(name, ".span-") } +func addInt64WithOverflow(a int64, b int64) (c int64, ok bool) { + c = a + b + return c, (c > a) == (b > 0) +} + +// mulInt64WithOverflow checks for overflow in multiplying two int64s. See +// https://groups.google.com/g/golang-nuts/c/h5oSN5t3Au4/m/KaNQREhZh0QJ +func mulInt64WithOverflow(a, b int64) (c int64, ok bool) { + const mostPositive = 1<<63 - 1 + const mostNegative = -(mostPositive + 1) + c = a * b + if a == 0 || b == 0 || a == 1 || b == 1 { + return c, true + } + if a == mostNegative || b == mostNegative { + return c, false + } + return c, c/b == a +} + // Resources implementation func (rc *resources) checkMemory(rsvp int64, prio uint8) error { - // overflow check; this also has the side effect that we cannot reserve negative memory. - newmem := rc.memory + rsvp - limit := rc.limit.GetMemoryLimit() - threshold := (1 + int64(prio)) * limit / 256 + if rsvp < 0 { + return fmt.Errorf("can't reserve negative memory. rsvp=%v", rsvp) + } - if newmem > threshold { + limit := rc.limit.GetMemoryLimit() + if limit == math.MaxInt64 { + // Special case where we've set max limits. + return nil + } + + newmem, addOk := addInt64WithOverflow(rc.memory, rsvp) + + threshold, mulOk := mulInt64WithOverflow(1+int64(prio), limit) + if !mulOk { + thresholdBig := big.NewInt(limit) + thresholdBig = thresholdBig.Mul(thresholdBig, big.NewInt(1+int64(prio))) + thresholdBig.Rsh(thresholdBig, 8) // Divide 256 + if !thresholdBig.IsInt64() { + // Shouldn't happen since the threshold can only be <= limit + threshold = limit + } + threshold = thresholdBig.Int64() + } else { + threshold = threshold / 256 + } + + if !addOk || newmem > threshold { return &errMemoryLimitExceeded{ current: rc.memory, attempted: rsvp, diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/sys_not_unix.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/sys_not_unix.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/sys_not_unix.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/sys_not_unix.go diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/sys_unix.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/sys_unix.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/sys_unix.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/sys_unix.go diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/sys_windows.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/sys_windows.go similarity index 100% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/sys_windows.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/sys_windows.go diff --git a/vendor/github.com/libp2p/go-libp2p-resource-manager/trace.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/trace.go similarity index 99% rename from vendor/github.com/libp2p/go-libp2p-resource-manager/trace.go rename to vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/trace.go index ae871a0a3..1af71edd7 100644 --- a/vendor/github.com/libp2p/go-libp2p-resource-manager/trace.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/resource-manager/trace.go @@ -11,7 +11,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) type trace struct { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/host/routed/routed.go b/vendor/github.com/libp2p/go-libp2p/p2p/host/routed/routed.go index 857b5378e..55c8d3474 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/host/routed/routed.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/host/routed/routed.go @@ -5,13 +5,13 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/protocol" logging "github.com/ipfs/go-log/v2" @@ -46,9 +46,12 @@ func Wrap(h host.Host, r Routing) *RoutedHost { // RoutedHost's Connect differs in that if the host has no addresses for a // given peer, it will use its routing system to try to find some. func (rh *RoutedHost) Connect(ctx context.Context, pi peer.AddrInfo) error { - // first, check if we're already connected. - if rh.Network().Connectedness(pi.ID) == network.Connected { - return nil + // first, check if we're already connected unless force direct dial. + forceDirect, _ := network.GetForceDirectDial(ctx) + if !forceDirect { + if rh.Network().Connectedness(pi.ID) == network.Connected { + return nil + } } // if we were given some addresses, keep + use them. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/conn.go index 1abef546f..ed4e847e5 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/conn.go @@ -3,7 +3,7 @@ package mplex import ( "context" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mp "github.com/libp2p/go-mplex" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/stream.go b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/stream.go index 64b70fbde..53e9e6daf 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/stream.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/stream.go @@ -3,7 +3,7 @@ package mplex import ( "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mp "github.com/libp2p/go-mplex" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/transport.go index f24c1cc7c..b7fbe84c7 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/mplex/transport.go @@ -3,7 +3,7 @@ package mplex import ( "net" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mp "github.com/libp2p/go-mplex" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream/multistream.go b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream/multistream.go index 1668c0b90..bf9d41630 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream/multistream.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/muxer-multistream/multistream.go @@ -7,7 +7,7 @@ import ( "net" "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" mss "github.com/multiformats/go-multistream" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/conn.go index 4feff1dea..40c4af405 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/conn.go @@ -3,9 +3,9 @@ package yamux import ( "context" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-yamux/v3" + "github.com/libp2p/go-yamux/v4" ) // conn implements mux.MuxedConn over yamux.Session. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/stream.go b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/stream.go index f75e77d65..b50bc0bb8 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/stream.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/stream.go @@ -3,9 +3,9 @@ package yamux import ( "time" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-yamux/v3" + "github.com/libp2p/go-yamux/v4" ) // stream implements mux.MuxedStream over yamux.Stream. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/transport.go index 74ed7145b..df4ff1be3 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/muxer/yamux/transport.go @@ -1,13 +1,13 @@ package yamux import ( - "io/ioutil" + "io" "math" "net" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" - "github.com/libp2p/go-yamux/v3" + "github.com/libp2p/go-yamux/v4" ) var DefaultTransport *Transport @@ -21,7 +21,7 @@ func init() { // totally unacceptable. config.MaxStreamWindowSize = uint32(16 * 1024 * 1024) // don't spam - config.LogOutput = ioutil.Discard + config.LogOutput = io.Discard // We always run over a security transport that buffers internally // (i.e., uses a block cipher). config.ReadBufSize = 0 @@ -38,12 +38,17 @@ type Transport yamux.Config var _ network.Multiplexer = &Transport{} func (t *Transport) NewConn(nc net.Conn, isServer bool, scope network.PeerScope) (network.MuxedConn, error) { + var newSpan func() (yamux.MemoryManager, error) + if scope != nil { + newSpan = func() (yamux.MemoryManager, error) { return scope.BeginSpan() } + } + var s *yamux.Session var err error if isServer { - s, err = yamux.Server(nc, t.Config(), scope) + s, err = yamux.Server(nc, t.Config(), newSpan) } else { - s, err = yamux.Client(nc, t.Config(), scope) + s, err = yamux.Client(nc, t.Config(), newSpan) } if err != nil { return nil, err diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream/ssms.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream/ssms.go index 46bb334a8..595d8dfde 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream/ssms.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/conn-security-multistream/ssms.go @@ -6,8 +6,9 @@ import ( "log" "net" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + mss "github.com/multiformats/go-multistream" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/connmgr.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/connmgr.go index b73e3a71d..3a1acf0db 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/connmgr.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/connmgr.go @@ -7,9 +7,10 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/benbjohnson/clock" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" @@ -27,6 +28,8 @@ var log = logging.Logger("connmgr") type BasicConnMgr struct { *decayer + clock clock.Clock + cfg *config segments segments @@ -74,7 +77,7 @@ func (ss *segments) countPeers() (count int) { return count } -func (s *segment) tagInfoFor(p peer.ID) *peerInfo { +func (s *segment) tagInfoFor(p peer.ID, now time.Time) *peerInfo { pi, ok := s.peers[p] if ok { return pi @@ -82,7 +85,7 @@ func (s *segment) tagInfoFor(p peer.ID) *peerInfo { // create a temporary peer to buffer early tags before the Connected notification arrives. pi = &peerInfo{ id: p, - firstSeen: time.Now(), // this timestamp will be updated when the first Connected notification arrives. + firstSeen: now, // this timestamp will be updated when the first Connected notification arrives. temp: true, tags: make(map[string]int), decaying: make(map[*decayingTag]*connmgr.DecayingValue), @@ -102,6 +105,7 @@ func NewConnManager(low, hi int, opts ...Option) (*BasicConnMgr, error) { lowWater: low, gracePeriod: time.Minute, silencePeriod: 10 * time.Second, + clock: clock.New(), } for _, o := range opts { if err := o(cfg); err != nil { @@ -116,6 +120,7 @@ func NewConnManager(low, hi int, opts ...Option) (*BasicConnMgr, error) { cm := &BasicConnMgr{ cfg: cfg, + clock: cfg.clock, protected: make(map[peer.ID]map[string]struct{}, 16), segments: func() (ret segments) { for i := range ret { @@ -167,7 +172,7 @@ func (cm *BasicConnMgr) memoryEmergency() { // finally, update the last trim time. cm.lastTrimMu.Lock() - cm.lastTrim = time.Now() + cm.lastTrim = cm.clock.Now() cm.lastTrimMu.Unlock() } @@ -243,19 +248,11 @@ type peerInfo struct { type peerInfos []peerInfo -func (p peerInfos) SortByValue() { - sort.Slice(p, func(i, j int) bool { - left, right := p[i], p[j] - // temporary peers are preferred for pruning. - if left.temp != right.temp { - return left.temp - } - // otherwise, compare by value. - return left.value < right.value - }) -} - -func (p peerInfos) SortByValueAndStreams() { +// SortByValueAndStreams sorts peerInfos by their value and stream count. It +// will sort peers with no streams before those with streams (all else being +// equal). If `sortByMoreStreams` is true it will sort peers with more streams +// before those with fewer streams. This is useful to prioritize freeing memory. +func (p peerInfos) SortByValueAndStreams(sortByMoreStreams bool) { sort.Slice(p, func(i, j int) bool { left, right := p[i], p[j] // temporary peers are preferred for pruning. @@ -278,12 +275,21 @@ func (p peerInfos) SortByValueAndStreams() { } leftIncoming, leftStreams := incomingAndStreams(left.conns) rightIncoming, rightStreams := incomingAndStreams(right.conns) + // prefer closing inactive connections (no streams open) + if rightStreams != leftStreams && (leftStreams == 0 || rightStreams == 0) { + return leftStreams < rightStreams + } // incoming connections are preferred for pruning if leftIncoming != rightIncoming { return leftIncoming } - // prune connections with a higher number of streams first - return rightStreams < leftStreams + + if sortByMoreStreams { + // prune connections with a higher number of streams first + return rightStreams < leftStreams + } else { + return leftStreams < rightStreams + } }) } @@ -310,7 +316,7 @@ func (cm *BasicConnMgr) background() { interval = cm.cfg.silencePeriod } - ticker := time.NewTicker(interval) + ticker := cm.clock.Ticker(interval) defer ticker.Stop() for { @@ -335,7 +341,7 @@ func (cm *BasicConnMgr) doTrim() { if count == atomic.LoadUint64(&cm.trimCount) { cm.trim() cm.lastTrimMu.Lock() - cm.lastTrim = time.Now() + cm.lastTrim = cm.clock.Now() cm.lastTrimMu.Unlock() atomic.AddUint64(&cm.trimCount, 1) } @@ -368,7 +374,7 @@ func (cm *BasicConnMgr) getConnsToCloseEmergency(target int) []network.Conn { cm.plk.RUnlock() // Sort peers according to their value. - candidates.SortByValueAndStreams() + candidates.SortByValueAndStreams(true) selected := make([]network.Conn, 0, target+10) for _, inf := range candidates { @@ -398,7 +404,7 @@ func (cm *BasicConnMgr) getConnsToCloseEmergency(target int) []network.Conn { } cm.plk.RUnlock() - candidates.SortByValueAndStreams() + candidates.SortByValueAndStreams(true) for _, inf := range candidates { if target <= 0 { break @@ -426,7 +432,7 @@ func (cm *BasicConnMgr) getConnsToClose() []network.Conn { candidates := make(peerInfos, 0, cm.segments.countPeers()) var ncandidates int - gracePeriodStart := time.Now().Add(-cm.cfg.gracePeriod) + gracePeriodStart := cm.clock.Now().Add(-cm.cfg.gracePeriod) cm.plk.RLock() for _, s := range cm.segments { @@ -459,7 +465,7 @@ func (cm *BasicConnMgr) getConnsToClose() []network.Conn { } // Sort peers according to their value. - candidates.SortByValue() + candidates.SortByValueAndStreams(false) target := ncandidates - cm.cfg.lowWater @@ -528,7 +534,7 @@ func (cm *BasicConnMgr) TagPeer(p peer.ID, tag string, val int) { s.Lock() defer s.Unlock() - pi := s.tagInfoFor(p) + pi := s.tagInfoFor(p, cm.clock.Now()) // Update the total value of the peer. pi.value += val - pi.tags[tag] @@ -558,7 +564,7 @@ func (cm *BasicConnMgr) UpsertTag(p peer.ID, tag string, upsert func(int) int) { s.Lock() defer s.Unlock() - pi := s.tagInfoFor(p) + pi := s.tagInfoFor(p, cm.clock.Now()) oldval := pi.tags[tag] newval := upsert(oldval) @@ -628,7 +634,7 @@ func (nn *cmNotifee) Connected(n network.Network, c network.Conn) { if !ok { pinfo = &peerInfo{ id: id, - firstSeen: time.Now(), + firstSeen: cm.clock.Now(), tags: make(map[string]int), decaying: make(map[*decayingTag]*connmgr.DecayingValue), conns: make(map[network.Conn]time.Time), @@ -639,7 +645,7 @@ func (nn *cmNotifee) Connected(n network.Network, c network.Conn) { // Connected notification arrived: flip the temporary flag, and update the firstSeen // timestamp to the real one. pinfo.temp = false - pinfo.firstSeen = time.Now() + pinfo.firstSeen = cm.clock.Now() } _, ok = pinfo.conns[c] @@ -648,7 +654,7 @@ func (nn *cmNotifee) Connected(n network.Network, c network.Conn) { return } - pinfo.conns[c] = time.Now() + pinfo.conns[c] = cm.clock.Now() atomic.AddInt32(&cm.connCount, 1) } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/decay.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/decay.go index 189759a18..0819bd213 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/decay.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/decay.go @@ -6,8 +6,8 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/peer" "github.com/benbjohnson/clock" ) @@ -62,9 +62,9 @@ type DecayerCfg struct { // WithDefaults writes the default values on this DecayerConfig instance, // and returns itself for chainability. // -// cfg := (&DecayerCfg{}).WithDefaults() -// cfg.Resolution = 30 * time.Second -// t := NewDecayer(cfg, cm) +// cfg := (&DecayerCfg{}).WithDefaults() +// cfg.Resolution = 30 * time.Second +// t := NewDecayer(cfg, cm) func (cfg *DecayerCfg) WithDefaults() *DecayerCfg { cfg.Resolution = DefaultResolution return cfg @@ -221,7 +221,7 @@ func (d *decayer) process() { s := d.mgr.segments.get(peer) s.Lock() - p := s.tagInfoFor(peer) + p := s.tagInfoFor(peer, d.clock.Now()) v, ok := p.decaying[tag] if !ok { v = &connmgr.DecayingValue{ @@ -244,7 +244,7 @@ func (d *decayer) process() { s := d.mgr.segments.get(rm.peer) s.Lock() - p := s.tagInfoFor(rm.peer) + p := s.tagInfoFor(rm.peer, d.clock.Now()) v, ok := p.decaying[rm.tag] if !ok { s.Unlock() diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/options.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/options.go index 76b4ef386..cde1fd792 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/options.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/options.go @@ -3,6 +3,8 @@ package connmgr import ( "errors" "time" + + "github.com/benbjohnson/clock" ) // config is the configuration struct for the basic connection manager. @@ -13,6 +15,7 @@ type config struct { silencePeriod time.Duration decayer *DecayerCfg emergencyTrim bool + clock clock.Clock } // Option represents an option for the basic connection manager. @@ -26,6 +29,14 @@ func DecayerConfig(opts *DecayerCfg) Option { } } +// WithClock sets the internal clock impl +func WithClock(c clock.Clock) Option { + return func(cfg *config) error { + cfg.clock = c + return nil + } +} + // WithGracePeriod sets the grace period. // The grace period is the time a newly opened connection is given before it becomes // subject to pruning. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_cgo.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_cgo.go index b048111f3..cb7bacef8 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_cgo.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_cgo.go @@ -1,5 +1,4 @@ -//go:build cgo -// +build cgo +//go:build cgo && !nowatchdog package connmgr diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_no_cgo.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_no_cgo.go index fb83c286d..4f26aa2a8 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_no_cgo.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/connmgr/watchdog_no_cgo.go @@ -1,5 +1,4 @@ -//go:build !cgo -// +build !cgo +//go:build !cgo || nowatchdog package connmgr diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/protector.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/protector.go index ed63a690b..643e904d2 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/protector.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/protector.go @@ -4,7 +4,7 @@ import ( "errors" "net" - ipnet "github.com/libp2p/go-libp2p-core/pnet" + ipnet "github.com/libp2p/go-libp2p/core/pnet" ) // NewProtectedConn creates a new protected connection diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/psk_conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/psk_conn.go index 5d35d8794..c600c8d09 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/psk_conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/pnet/psk_conn.go @@ -6,7 +6,7 @@ import ( "io" "net" - "github.com/libp2p/go-libp2p-core/pnet" + "github.com/libp2p/go-libp2p/core/pnet" "github.com/davidlazar/go-crypto/salsa20" pool "github.com/libp2p/go-buffer-pool" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dial.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dial.go index b998be7d2..6a3d18ff2 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dial.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dial.go @@ -2,18 +2,11 @@ package reuseport import ( "context" - "net" - "github.com/libp2p/go-reuseport" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) -type dialer interface { - Dial(network, addr string) (net.Conn, error) - DialContext(ctx context.Context, network, addr string) (net.Conn, error) -} - // Dial dials the given multiaddr, reusing ports we're currently listening on if // possible. // @@ -31,7 +24,7 @@ func (t *Transport) DialContext(ctx context.Context, raddr ma.Multiaddr) (manet. if err != nil { return nil, err } - var d dialer + var d *dialer switch network { case "tcp4": d = t.v4.getDialer(network) @@ -52,7 +45,7 @@ func (t *Transport) DialContext(ctx context.Context, raddr ma.Multiaddr) (manet. return maconn, nil } -func (n *network) getDialer(network string) dialer { +func (n *network) getDialer(network string) *dialer { n.mu.RLock() d := n.dialer n.mu.RUnlock() @@ -61,53 +54,9 @@ func (n *network) getDialer(network string) dialer { defer n.mu.Unlock() if n.dialer == nil { - n.dialer = n.makeDialer(network) + n.dialer = newDialer(n.listeners) } d = n.dialer } return d } - -func (n *network) makeDialer(network string) dialer { - if !reuseport.Available() { - log.Debug("reuseport not available") - return &net.Dialer{} - } - - var unspec net.IP - switch network { - case "tcp4": - unspec = net.IPv4zero - case "tcp6": - unspec = net.IPv6unspecified - default: - panic("invalid network: must be either tcp4 or tcp6") - } - - // How many ports are we listening on. - var port = 0 - for l := range n.listeners { - newPort := l.Addr().(*net.TCPAddr).Port - switch { - case newPort == 0: // Any port, ignore (really, we shouldn't get this case...). - case port == 0: // Haven't selected a port yet, choose this one. - port = newPort - case newPort == port: // Same as the selected port, continue... - default: // Multiple ports, use the multi dialer - return newMultiDialer(unspec, n.listeners) - } - } - - // None. - if port == 0 { - return &net.Dialer{} - } - - // One. Always dial from the single port we're listening on. - laddr := &net.TCPAddr{ - IP: unspec, - Port: port, - } - - return (*singleDialer)(laddr) -} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dialer.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dialer.go new file mode 100644 index 000000000..2efc02d39 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/dialer.go @@ -0,0 +1,114 @@ +package reuseport + +import ( + "context" + "fmt" + "math/rand" + "net" + + "github.com/libp2p/go-netroute" +) + +type dialer struct { + // All address that are _not_ loopback or unspecified (0.0.0.0 or ::). + specific []*net.TCPAddr + // All loopback addresses (127.*.*.*, ::1). + loopback []*net.TCPAddr + // Unspecified addresses (0.0.0.0, ::) + unspecified []*net.TCPAddr +} + +func (d *dialer) Dial(network, addr string) (net.Conn, error) { + return d.DialContext(context.Background(), network, addr) +} + +func randAddr(addrs []*net.TCPAddr) *net.TCPAddr { + if len(addrs) > 0 { + return addrs[rand.Intn(len(addrs))] + } + return nil +} + +// DialContext dials a target addr. +// +// In-order: +// +// 1. If we're _explicitly_ listening on the prefered source address for the destination address +// (per the system's routes), we'll use that listener's port as the source port. +// 2. If we're listening on one or more _unspecified_ addresses (zero address), we'll pick a source +// port from one of these listener's. +// 3. Otherwise, we'll let the system pick the source port. +func (d *dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { + // We only check this case if the user is listening on a specific address (loopback or + // otherwise). Generally, users will listen on the "unspecified" address (0.0.0.0 or ::) and + // we can skip this section. + // + // This lets us avoid resolving the address twice, in most cases. + if len(d.specific) > 0 || len(d.loopback) > 0 { + tcpAddr, err := net.ResolveTCPAddr(network, addr) + if err != nil { + return nil, err + } + ip := tcpAddr.IP + if !ip.IsLoopback() && !ip.IsGlobalUnicast() { + return nil, fmt.Errorf("undialable IP: %s", ip) + } + + // If we're listening on some specific address and that specific address happens to + // be the preferred source address for the target destination address, we try to + // dial with that address/port. + // + // We skip this check if we _aren't_ listening on any specific addresses, because + // checking routing tables can be expensive and users rarely listen on specific IP + // addresses. + if len(d.specific) > 0 { + if router, err := netroute.New(); err == nil { + if _, _, preferredSrc, err := router.Route(ip); err == nil { + for _, optAddr := range d.specific { + if optAddr.IP.Equal(preferredSrc) { + return reuseDial(ctx, optAddr, network, addr) + } + } + } + } + } + + // Otherwise, if we are listening on a loopback address and the destination is also + // a loopback address, use the port from our loopback listener. + if len(d.loopback) > 0 && ip.IsLoopback() { + return reuseDial(ctx, randAddr(d.loopback), network, addr) + } + } + + // If we're listening on any uspecified addresses, use a randomly chosen port from one of + // these listeners. + if len(d.unspecified) > 0 { + return reuseDial(ctx, randAddr(d.unspecified), network, addr) + } + + // Finally, just pick a random port. + var dialer net.Dialer + return dialer.DialContext(ctx, network, addr) +} + +func newDialer(listeners map[*listener]struct{}) *dialer { + specific := make([]*net.TCPAddr, 0) + loopback := make([]*net.TCPAddr, 0) + unspecified := make([]*net.TCPAddr, 0) + + for l := range listeners { + addr := l.Addr().(*net.TCPAddr) + if addr.IP.IsLoopback() { + loopback = append(loopback, addr) + } else if addr.IP.IsUnspecified() { + unspecified = append(unspecified, addr) + } else { + specific = append(specific, addr) + } + } + return &dialer{ + specific: specific, + loopback: loopback, + unspecified: unspecified, + } +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/multidialer.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/multidialer.go deleted file mode 100644 index a3b5e2e99..000000000 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/multidialer.go +++ /dev/null @@ -1,90 +0,0 @@ -package reuseport - -import ( - "context" - "fmt" - "math/rand" - "net" - - "github.com/libp2p/go-netroute" -) - -type multiDialer struct { - listeningAddresses []*net.TCPAddr - loopback []*net.TCPAddr - unspecified []*net.TCPAddr - fallback net.TCPAddr -} - -func (d *multiDialer) Dial(network, addr string) (net.Conn, error) { - return d.DialContext(context.Background(), network, addr) -} - -func randAddr(addrs []*net.TCPAddr) *net.TCPAddr { - if len(addrs) > 0 { - return addrs[rand.Intn(len(addrs))] - } - return nil -} - -// DialContext dials a target addr. -// Dialing preference is -// * If there is a listener on the local interface the OS expects to use to route towards addr, use that. -// * If there is a listener on a loopback address, addr is loopback, use that. -// * If there is a listener on an undefined address (0.0.0.0 or ::), use that. -// * Use the fallback IP specified during construction, with a port that's already being listened on, if one exists. -func (d *multiDialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { - tcpAddr, err := net.ResolveTCPAddr(network, addr) - if err != nil { - return nil, err - } - ip := tcpAddr.IP - if !ip.IsLoopback() && !ip.IsGlobalUnicast() { - return nil, fmt.Errorf("undialable IP: %s", ip) - } - - if router, err := netroute.New(); err == nil { - if _, _, preferredSrc, err := router.Route(ip); err == nil { - for _, optAddr := range d.listeningAddresses { - if optAddr.IP.Equal(preferredSrc) { - return reuseDial(ctx, optAddr, network, addr) - } - } - } - } - - if ip.IsLoopback() && len(d.loopback) > 0 { - return reuseDial(ctx, randAddr(d.loopback), network, addr) - } - if len(d.unspecified) == 0 { - return reuseDial(ctx, &d.fallback, network, addr) - } - - return reuseDial(ctx, randAddr(d.unspecified), network, addr) -} - -func newMultiDialer(unspec net.IP, listeners map[*listener]struct{}) (m dialer) { - addrs := make([]*net.TCPAddr, 0) - loopback := make([]*net.TCPAddr, 0) - unspecified := make([]*net.TCPAddr, 0) - existingPort := 0 - - for l := range listeners { - addr := l.Addr().(*net.TCPAddr) - addrs = append(addrs, addr) - if addr.IP.IsLoopback() { - loopback = append(loopback, addr) - } else if addr.IP.IsGlobalUnicast() && existingPort == 0 { - existingPort = addr.Port - } else if addr.IP.IsUnspecified() { - unspecified = append(unspecified, addr) - } - } - m = &multiDialer{ - listeningAddresses: addrs, - loopback: loopback, - unspecified: unspecified, - fallback: net.TCPAddr{IP: unspec, Port: existingPort}, - } - return -} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/reuseport_posix.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/reuseport_posix.go index a40035477..0b5771bb7 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/reuseport_posix.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/reuseport_posix.go @@ -1,5 +1,4 @@ //go:build !plan9 -// +build !plan9 package reuseport diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/singledialer.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/singledialer.go deleted file mode 100644 index b15dae80b..000000000 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/singledialer.go +++ /dev/null @@ -1,16 +0,0 @@ -package reuseport - -import ( - "context" - "net" -) - -type singleDialer net.TCPAddr - -func (d *singleDialer) Dial(network, address string) (net.Conn, error) { - return d.DialContext(context.Background(), network, address) -} - -func (d *singleDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { - return reuseDial(ctx, (*net.TCPAddr)(d), network, address) -} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/transport.go index 37fb446cb..ba7b9debf 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/reuseport/transport.go @@ -31,5 +31,5 @@ type Transport struct { type network struct { mu sync.RWMutex listeners map[*listener]struct{} - dialer dialer + dialer *dialer } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_error.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_error.go index f2986348b..711ee0607 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_error.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_error.go @@ -5,7 +5,7 @@ import ( "os" "strings" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_sync.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_sync.go index f24ecd3c4..2a8ff4317 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_sync.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_sync.go @@ -4,8 +4,8 @@ import ( "context" "sync" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) // dialWorkerFunc is used by dialSync to spawn a new dial worker diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_worker.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_worker.go index cf9dfe592..ff339d2f2 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_worker.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/dial_worker.go @@ -4,8 +4,8 @@ import ( "context" "sync" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/limiter.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/limiter.go index 6b49d8ec0..ccfe7d237 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/limiter.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/limiter.go @@ -7,8 +7,8 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm.go index 532ae2445..ece0986df 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm.go @@ -10,15 +10,16 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/metrics" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/metrics" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/transport" logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" + madns "github.com/multiformats/go-multiaddr-dns" ) const ( @@ -54,6 +55,14 @@ func WithConnectionGater(gater connmgr.ConnectionGater) Option { } } +// WithMultiaddrResolver sets a custom multiaddress resolver +func WithMultiaddrResolver(maResolver *madns.Resolver) Option { + return func(s *Swarm) error { + s.maResolver = maResolver + return nil + } +} + // WithMetrics sets a metrics reporter func WithMetrics(reporter metrics.Reporter) Option { return func(s *Swarm) error { @@ -127,6 +136,8 @@ type Swarm struct { m map[int]transport.Transport } + maResolver *madns.Resolver + // stream handlers streamh atomic.Value @@ -153,6 +164,7 @@ func NewSwarm(local peer.ID, peers peerstore.Peerstore, opts ...Option) (*Swarm, ctxCancel: cancel, dialTimeout: defaultDialTimeout, dialTimeoutLocal: defaultDialTimeoutLocal, + maResolver: madns.DefaultResolver, } s.conns.m = make(map[peer.ID][]*Conn) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_conn.go index 64fb2ed5d..779ee3737 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_conn.go @@ -8,10 +8,10 @@ import ( "sync/atomic" "time" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_dial.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_dial.go index 927560281..f5e5cba8d 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_dial.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_dial.go @@ -7,15 +7,21 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/canonicallog" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" + madns "github.com/multiformats/go-multiaddr-dns" manet "github.com/multiformats/go-multiaddr/net" ) +// The maximum number of address resolution steps we'll perform for a single +// peer (for all addresses). +const maxAddressResolution = 32 + // Diagram of dial sync: // // many callers of Dial() synched w. dials many addrs results to callers @@ -155,7 +161,7 @@ var BackoffMax = time.Minute * 5 // Backoff is not exponential, it's quadratic and computed according to the // following formula: // -// BackoffBase + BakoffCoef * PriorBackoffs^2 +// BackoffBase + BakoffCoef * PriorBackoffs^2 // // Where PriorBackoffs is the number of previous backoffs. func (db *DialBackoff) AddBackoff(p peer.ID, addr ma.Multiaddr) { @@ -292,7 +298,32 @@ func (s *Swarm) addrsForDial(ctx context.Context, p peer.ID) ([]ma.Multiaddr, er return nil, ErrNoAddresses } - goodAddrs := s.filterKnownUndialables(p, peerAddrs) + peerAddrsAfterTransportResolved := make([]ma.Multiaddr, 0, len(peerAddrs)) + for _, a := range peerAddrs { + tpt := s.TransportForDialing(a) + resolver, ok := tpt.(transport.Resolver) + if ok { + resolvedAddrs, err := resolver.Resolve(ctx, a) + if err != nil { + log.Warnf("Failed to resolve multiaddr %s by transport %v: %v", a, tpt, err) + continue + } + peerAddrsAfterTransportResolved = append(peerAddrsAfterTransportResolved, resolvedAddrs...) + } else { + peerAddrsAfterTransportResolved = append(peerAddrsAfterTransportResolved, a) + } + } + + // Resolve dns or dnsaddrs + resolved, err := s.resolveAddrs(ctx, peer.AddrInfo{ + ID: p, + Addrs: peerAddrsAfterTransportResolved, + }) + if err != nil { + return nil, err + } + + goodAddrs := s.filterKnownUndialables(p, resolved) if forceDirect, _ := network.GetForceDirectDial(ctx); forceDirect { goodAddrs = ma.FilterAddrs(goodAddrs, s.nonProxyAddr) } @@ -301,7 +332,71 @@ func (s *Swarm) addrsForDial(ctx context.Context, p peer.ID) ([]ma.Multiaddr, er return nil, ErrNoGoodAddresses } - return goodAddrs, nil + s.peers.AddAddrs(p, goodAddrs, peerstore.TempAddrTTL) + + return resolved, nil +} + +func (s *Swarm) resolveAddrs(ctx context.Context, pi peer.AddrInfo) ([]ma.Multiaddr, error) { + proto := ma.ProtocolWithCode(ma.P_P2P).Name + p2paddr, err := ma.NewMultiaddr("/" + proto + "/" + pi.ID.Pretty()) + if err != nil { + return nil, err + } + + resolveSteps := 0 + + // Recursively resolve all addrs. + // + // While the toResolve list is non-empty: + // * Pop an address off. + // * If the address is fully resolved, add it to the resolved list. + // * Otherwise, resolve it and add the results to the "to resolve" list. + toResolve := append(([]ma.Multiaddr)(nil), pi.Addrs...) + resolved := make([]ma.Multiaddr, 0, len(pi.Addrs)) + for len(toResolve) > 0 { + // pop the last addr off. + addr := toResolve[len(toResolve)-1] + toResolve = toResolve[:len(toResolve)-1] + + // if it's resolved, add it to the resolved list. + if !madns.Matches(addr) { + resolved = append(resolved, addr) + continue + } + + resolveSteps++ + + // We've resolved too many addresses. We can keep all the fully + // resolved addresses but we'll need to skip the rest. + if resolveSteps >= maxAddressResolution { + log.Warnf( + "peer %s asked us to resolve too many addresses: %s/%s", + pi.ID, + resolveSteps, + maxAddressResolution, + ) + continue + } + + // otherwise, resolve it + reqaddr := addr.Encapsulate(p2paddr) + resaddrs, err := s.maResolver.Resolve(ctx, reqaddr) + if err != nil { + log.Infof("error resolving %s: %s", reqaddr, err) + } + + // add the results to the toResolve list. + for _, res := range resaddrs { + pi, err := peer.AddrInfoFromP2pAddr(res) + if err != nil { + log.Infof("error parsing %s: %s", res, err) + } + toResolve = append(toResolve, pi.Addrs...) + } + } + + return resolved, nil } func (s *Swarm) dialNextAddr(ctx context.Context, p peer.ID, addr ma.Multiaddr, resch chan dialResult) error { @@ -344,7 +439,7 @@ func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) []ma.Mul } } - return ma.FilterAddrs(addrs, + return maybeRemoveWebTransportAddrs(ma.FilterAddrs(addrs, func(addr ma.Multiaddr) bool { return !ma.Contains(ourAddrs, addr) }, s.canDial, // TODO: Consider allowing link-local addresses @@ -352,7 +447,7 @@ func (s *Swarm) filterKnownUndialables(p peer.ID, addrs []ma.Multiaddr) []ma.Mul func(addr ma.Multiaddr) bool { return s.gater == nil || s.gater.InterceptAddrDial(p, addr) }, - ) + )) } // limitedDial will start a dial to the given peer when @@ -403,7 +498,7 @@ func (s *Swarm) dialAddr(ctx context.Context, p peer.ID, addr ma.Multiaddr) (tra return connC, nil } -// TODO We should have a `IsFdConsuming() bool` method on the `Transport` interface in go-libp2p-core/transport. +// TODO We should have a `IsFdConsuming() bool` method on the `Transport` interface in go-libp2p/core/transport. // This function checks if any of the transport protocols in the address requires a file descriptor. // For now: // A Non-circuit address which has the TCP/UNIX protocol is deemed FD consuming. @@ -435,3 +530,41 @@ func isRelayAddr(addr ma.Multiaddr) bool { _, err := addr.ValueForProtocol(ma.P_CIRCUIT) return err == nil } + +func isWebTransport(addr ma.Multiaddr) bool { + _, err := addr.ValueForProtocol(ma.P_WEBTRANSPORT) + return err == nil +} + +func isQUIC(addr ma.Multiaddr) bool { + _, err := addr.ValueForProtocol(ma.P_QUIC) + return err == nil && !isWebTransport(addr) +} + +// If we have QUIC addresses, we don't want to dial WebTransport addresses. +// It's better to have a native QUIC connection. +// Note that this is a hack. The correct solution would be a proper +// Happy-Eyeballs-style dialing. +func maybeRemoveWebTransportAddrs(addrs []ma.Multiaddr) []ma.Multiaddr { + var hasQuic, hasWebTransport bool + for _, addr := range addrs { + if isQUIC(addr) { + hasQuic = true + } + if isWebTransport(addr) { + hasWebTransport = true + } + } + if !hasWebTransport || !hasQuic { + return addrs + } + var c int + for _, addr := range addrs { + if isWebTransport(addr) { + continue + } + addrs[c] = addr + c++ + } + return addrs[:c] +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_listen.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_listen.go index 9159c5596..044da2e8d 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_listen.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_listen.go @@ -4,9 +4,9 @@ import ( "fmt" "time" - "github.com/libp2p/go-libp2p-core/canonicallog" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_stream.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_stream.go index 109cce580..7a5bb2750 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_stream.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_stream.go @@ -6,8 +6,8 @@ import ( "sync/atomic" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/protocol" ) // Validate Stream conforms to the go-libp2p-net Stream interface diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_transport.go index 21728ac3b..924f0384a 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/swarm/swarm_transport.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) @@ -19,6 +19,7 @@ func (s *Swarm) TransportForDialing(a ma.Multiaddr) transport.Transport { s.transports.RLock() defer s.transports.RUnlock() + if len(s.transports.m) == 0 { // make sure we're not just shutting down. if s.transports.m != nil { @@ -26,18 +27,15 @@ func (s *Swarm) TransportForDialing(a ma.Multiaddr) transport.Transport { } return nil } - - for _, p := range protocols { - transport, ok := s.transports.m[p.Code] - if !ok { - continue - } - if transport.Proxy() { - return transport + if isRelayAddr(a) { + return s.transports.m[ma.P_CIRCUIT] + } + for _, t := range s.transports.m { + if t.CanDial(a) { + return t } } - - return s.transports.m[protocols[len(protocols)-1].Code] + return nil } // TransportForListening retrieves the appropriate transport for listening on diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/conn.go index 4ee0edc40..2fa7af64b 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/conn.go @@ -3,8 +3,8 @@ package upgrader import ( "fmt" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/transport" ) type transportConn struct { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/listener.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/listener.go index cc462b53a..c07299c1a 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/listener.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/listener.go @@ -5,8 +5,8 @@ import ( "fmt" "sync" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/transport" logging "github.com/ipfs/go-log/v2" tec "github.com/jbenet/go-temp-err-catcher" @@ -51,11 +51,11 @@ func (l *listener) Close() error { // // This function does a few interesting things that should be noted: // -// 1. It logs and discards temporary/transient errors (errors with a Temporary() -// function that returns true). -// 2. It stops accepting new connections once AcceptQueueLength connections have -// been fully negotiated but not accepted. This gives us a basic backpressure -// mechanism while still allowing us to negotiate connections in parallel. +// 1. It logs and discards temporary/transient errors (errors with a Temporary() +// function that returns true). +// 2. It stops accepting new connections once AcceptQueueLength connections have +// been fully negotiated but not accepted. This gives us a basic backpressure +// mechanism while still allowing us to negotiate connections in parallel. func (l *listener) handleIncoming() { var wg sync.WaitGroup defer func() { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/upgrader.go b/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/upgrader.go index 4f8e71225..58347865a 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/upgrader.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/net/upgrader/upgrader.go @@ -7,15 +7,14 @@ import ( "net" "time" + "github.com/libp2p/go-libp2p/core/connmgr" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + ipnet "github.com/libp2p/go-libp2p/core/pnet" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/net/pnet" - "github.com/libp2p/go-libp2p-core/connmgr" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - ipnet "github.com/libp2p/go-libp2p-core/pnet" - "github.com/libp2p/go-libp2p-core/sec" - "github.com/libp2p/go-libp2p-core/transport" - manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/options.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/options.go index 22e047821..bfd2ed895 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/options.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/options.go @@ -1,7 +1,7 @@ package relay import ( - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ) type Resources struct { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/relay.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/relay.go index 3c626bd00..3b6f7adc8 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/relay.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/relay/relay.go @@ -8,13 +8,12 @@ import ( "sync/atomic" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - logging "github.com/ipfs/go-log/v2" pool "github.com/libp2p/go-buffer-pool" ma "github.com/multiformats/go-multiaddr" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/client.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/client.go index bdd9bf9eb..aa302e7e1 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/client.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/client.go @@ -5,12 +5,11 @@ import ( "io" "sync" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - logging "github.com/ipfs/go-log/v2" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/conn.go index fcca1bea2..23bde93d5 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/conn.go @@ -5,8 +5,8 @@ import ( "net" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/dial.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/dial.go index 4a1e0e6ea..2e5fc73b5 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/dial.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/dial.go @@ -5,15 +5,14 @@ import ( "fmt" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" pbv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/handlers.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/handlers.go index fa338f8f4..ef50b8e82 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/handlers.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/handlers.go @@ -3,11 +3,10 @@ package client import ( "time" + "github.com/libp2p/go-libp2p/core/network" pbv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - - "github.com/libp2p/go-libp2p-core/network" ) var ( diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/reservation.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/reservation.go index aebcfe74c..1cd451ad1 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/reservation.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/reservation.go @@ -5,15 +5,14 @@ import ( "fmt" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/record" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/transport.go index cd1c302d3..97fc1ce1a 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/client/transport.go @@ -5,11 +5,10 @@ import ( "fmt" "io" - "github.com/libp2p/go-libp2p-core/network" - - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto/voucher.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto/voucher.go index fe8e3aeec..fd50fccce 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto/voucher.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto/voucher.go @@ -3,10 +3,9 @@ package proto import ( "time" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/record" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" - - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/record" ) const RecordDomain = "libp2p-relay-rsvp" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/acl.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/acl.go index 050105132..4191556a3 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/acl.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/acl.go @@ -1,7 +1,7 @@ package relay import ( - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/constraints.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/constraints.go index 1b0087ec8..24353086f 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/constraints.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/constraints.go @@ -6,7 +6,8 @@ import ( "time" asnutil "github.com/libp2p/go-libp2p-asn-util" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/relay.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/relay.go index 2ff153f34..5e2d9f183 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/relay.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/relay/relay.go @@ -8,15 +8,14 @@ import ( "sync/atomic" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/record" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/proto" "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/record" - logging "github.com/ipfs/go-log/v2" pool "github.com/libp2p/go-buffer-pool" ma "github.com/multiformats/go-multiaddr" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/io.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/io.go index 911bad19f..de314b18e 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/io.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/io.go @@ -22,10 +22,10 @@ type DelimitedReader struct { // it can take multiple single byte Reads to read the length and another Read // to read the message payload. // However, this is not critical performance degradation as -// - the reader is utilized to read one (dialer, stop) or two messages (hop) during -// the handshake, so it's a drop in the water for the connection lifetime. -// - messages are small (max 4k) and the length fits in a couple of bytes, -// so overall we have at most three reads per message. +// - the reader is utilized to read one (dialer, stop) or two messages (hop) during +// the handshake, so it's a drop in the water for the connection lifetime. +// - messages are small (max 4k) and the length fits in a couple of bytes, +// so overall we have at most three reads per message. func NewDelimitedReader(r io.Reader, maxSize int) *DelimitedReader { return &DelimitedReader{r: r, buf: pool.Get(maxSize)} } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/pbconv.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/pbconv.go index a5b73f628..ae1b9b50b 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/pbconv.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/util/pbconv.go @@ -3,11 +3,10 @@ package util import ( "errors" + "github.com/libp2p/go-libp2p/core/peer" pbv1 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv1/pb" pbv2 "github.com/libp2p/go-libp2p/p2p/protocol/circuitv2/pb" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/holepuncher.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/holepuncher.go index 810608f20..7f2bbbd12 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/holepuncher.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/holepuncher.go @@ -7,13 +7,12 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" pb "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb" "github.com/libp2p/go-libp2p/p2p/protocol/identify" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-msgio/protoio" ma "github.com/multiformats/go-multiaddr" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/svc.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/svc.go index f7ca7c4a1..1df779fc3 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/svc.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/svc.go @@ -7,15 +7,14 @@ import ( "sync" "time" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" pb "github.com/libp2p/go-libp2p/p2p/protocol/holepunch/pb" "github.com/libp2p/go-libp2p/p2p/protocol/identify" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - logging "github.com/ipfs/go-log/v2" "github.com/libp2p/go-msgio/protoio" ma "github.com/multiformats/go-multiaddr" @@ -242,7 +241,7 @@ func (s *Service) handleNewStream(str network.Stream) { rtt, addrs, err := s.incomingHolePunch(str) if err != nil { s.tracer.ProtocolError(rp, err) - log.Debugw("error handling holepunching stream from", rp, "error", err) + log.Debugw("error handling holepunching stream from", "peer", rp, "error", err) str.Reset() return } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/tracer.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/tracer.go index 1512ba103..87aa61367 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/tracer.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/tracer.go @@ -6,7 +6,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/util.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/util.go index af7077570..825f855ee 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/util.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/holepunch/util.go @@ -3,9 +3,10 @@ package holepunch import ( "context" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go index 26a22b586..b9d95240e 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id.go @@ -7,25 +7,24 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" - - "github.com/libp2p/go-eventbus" - "github.com/libp2p/go-msgio/protoio" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/core/record" + "github.com/libp2p/go-libp2p/p2p/host/eventbus" pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" - ma "github.com/multiformats/go-multiaddr" - manet "github.com/multiformats/go-multiaddr/net" - msmux "github.com/multiformats/go-multistream" + "github.com/libp2p/go-msgio/protoio" "github.com/gogo/protobuf/proto" logging "github.com/ipfs/go-log/v2" + ma "github.com/multiformats/go-multiaddr" + manet "github.com/multiformats/go-multiaddr/net" + msmux "github.com/multiformats/go-multistream" ) var log = logging.Logger("net/identify") @@ -34,11 +33,7 @@ var log = logging.Logger("net/identify") // service. const ID = "/ipfs/id/1.0.0" -// LibP2PVersion holds the current protocol version for a client running this code -// TODO(jbenet): fix the versioning mess. -// XXX: Don't change this till 2020. You'll break all go-ipfs versions prior to -// 0.4.17 which asserted an exact version match. -const LibP2PVersion = "ipfs/0.1.0" +const DefaultProtocolVersion = "ipfs/0.1.0" const ServiceName = "libp2p.identify" @@ -86,12 +81,13 @@ type IDService interface { // useful information about the local peer. A sort of hello. // // The idService sends: -// * Our IPFS Protocol Version -// * Our IPFS Agent Version -// * Our public Listen Addresses +// - Our IPFS Protocol Version +// - Our IPFS Agent Version +// - Our public Listen Addresses type idService struct { - Host host.Host - UserAgent string + Host host.Host + UserAgent string + ProtocolVersion string ctx context.Context ctxCancel context.CancelFunc @@ -136,9 +132,15 @@ func NewIDService(h host.Host, opts ...Option) (*idService, error) { userAgent = cfg.userAgent } + protocolVersion := DefaultProtocolVersion + if cfg.protocolVersion != "" { + protocolVersion = cfg.protocolVersion + } + s := &idService{ - Host: h, - UserAgent: userAgent, + Host: h, + UserAgent: userAgent, + ProtocolVersion: protocolVersion, conns: make(map[network.Conn]chan struct{}), @@ -189,8 +191,10 @@ func (ids *idService) loop() { defer ids.refCount.Done() phs := make(map[peer.ID]*peerHandler) - sub, err := ids.Host.EventBus().Subscribe([]interface{}{&event.EvtLocalProtocolsUpdated{}, - &event.EvtLocalAddressesUpdated{}}, eventbus.BufSize(256)) + sub, err := ids.Host.EventBus().Subscribe([]interface{}{ + &event.EvtLocalProtocolsUpdated{}, + &event.EvtLocalAddressesUpdated{}, + }, eventbus.BufSize(256)) if err != nil { log.Errorf("failed to subscribe to events on the bus, err=%s", err) return @@ -490,7 +494,6 @@ func (ids *idService) writeChunkedIdentifyMsg(c network.Conn, snapshot *identify m := &pb.Identify{SignedPeerRecord: sr} err := writer.WriteMsg(m) return err - } func (ids *idService) createBaseIdentifyResponse( @@ -542,10 +545,8 @@ func (ids *idService) createBaseIdentifyResponse( } // set protocol versions - pv := LibP2PVersion - av := ids.UserAgent - mes.ProtocolVersion = &pv - mes.AgentVersion = &av + mes.ProtocolVersion = &ids.ProtocolVersion + mes.AgentVersion = &ids.UserAgent return mes } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_delta.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_delta.go index 467a101de..7f7c75f12 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_delta.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_delta.go @@ -3,11 +3,10 @@ package identify import ( "time" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" "github.com/libp2p/go-msgio/protoio" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go117.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go117.go index 42d6ff5b6..22be28a5e 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go117.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go117.go @@ -1,5 +1,4 @@ //go:build !go1.18 -// +build !go1.18 package identify diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go118.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go118.go index e4f477940..f934dc66e 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go118.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_go118.go @@ -1,5 +1,4 @@ //go:build go1.18 -// +build go1.18 package identify diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_push.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_push.go index 1f644d1ee..cbb47a9fa 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_push.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/id_push.go @@ -1,7 +1,7 @@ package identify import ( - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" ) // IDPush is the protocol.ID of the Identify push protocol. It sends full identify messages containing diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go index adfb4808c..bd72175dc 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/obsaddr.go @@ -7,11 +7,11 @@ import ( "sync" "time" - "github.com/libp2p/go-eventbus" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peerstore" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peerstore" + "github.com/libp2p/go-libp2p/p2p/host/eventbus" ma "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" @@ -51,9 +51,9 @@ type observation struct { // observedAddr is an entry for an address reported by our peers. // We only use addresses that: -// - have been observed at least 4 times in last 40 minutes. (counter symmetric nats) -// - have been observed at least once recently (10 minutes), because our position in the -// network, or network port mapppings, may have changed. +// - have been observed at least 4 times in last 40 minutes. (counter symmetric nats) +// - have been observed at least once recently (10 minutes), because our position in the +// network, or network port mapppings, may have changed. type observedAddr struct { addr ma.Multiaddr seenBy map[string]observation // peer(observer) address -> observation info diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/opts.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/opts.go index 0eb1d9664..38f505b69 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/opts.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/opts.go @@ -1,6 +1,7 @@ package identify type config struct { + protocolVersion string userAgent string disableSignedPeerRecord bool } @@ -8,6 +9,14 @@ type config struct { // Option is an option function for identify. type Option func(*config) +// ProtocolVersion sets the protocol version string that will be used to +// identify the family of protocols used by the peer. +func ProtocolVersion(s string) Option { + return func(cfg *config) { + cfg.protocolVersion = s + } +} + // UserAgent sets the user agent this node will identify itself with to peers. func UserAgent(ua string) Option { return func(cfg *config) { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go index 27d77f7c0..3cfed8270 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.pb.go @@ -5,10 +5,11 @@ package identify_pb import ( fmt "fmt" - proto "github.com/gogo/protobuf/proto" io "io" math "math" math_bits "math/bits" + + proto "github.com/gogo/protobuf/proto" ) // Reference imports to suppress errors if they are not otherwise used. @@ -102,8 +103,8 @@ type Identify struct { // signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord, // signed by the sending node. It contains the same addresses as the listenAddrs field, but // in a form that lets us share authenticated addrs with other peers. - // see github.com/libp2p/go-libp2p-core/record/pb/envelope.proto and - // github.com/libp2p/go-libp2p-core/peer/pb/peer_record.proto for message definitions. + // see github.com/libp2p/go-libp2p/core/record/pb/envelope.proto and + // github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto for message definitions. SignedPeerRecord []byte `protobuf:"bytes,8,opt,name=signedPeerRecord" json:"signedPeerRecord,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto index afc85253f..bdb283305 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/pb/identify.proto @@ -40,7 +40,7 @@ message Identify { // signedPeerRecord contains a serialized SignedEnvelope containing a PeerRecord, // signed by the sending node. It contains the same addresses as the listenAddrs field, but // in a form that lets us share authenticated addrs with other peers. - // see github.com/libp2p/go-libp2p-core/record/pb/envelope.proto and - // github.com/libp2p/go-libp2p-core/peer/pb/peer_record.proto for message definitions. + // see github.com/libp2p/go-libp2p/core/record/pb/envelope.proto and + // github.com/libp2p/go-libp2p/core/peer/pb/peer_record.proto for message definitions. optional bytes signedPeerRecord = 8; } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/peer_loop.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/peer_loop.go index 5fd312585..af8549339 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/peer_loop.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/identify/peer_loop.go @@ -7,11 +7,10 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" - "github.com/libp2p/go-libp2p-core/record" - + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/protocol" + "github.com/libp2p/go-libp2p/core/record" pb "github.com/libp2p/go-libp2p/p2p/protocol/identify/pb" "github.com/libp2p/go-msgio/protoio" diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go index 2a977de4b..583eea5c3 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/protocol/ping/ping.go @@ -12,9 +12,9 @@ import ( logging "github.com/ipfs/go-log/v2" pool "github.com/libp2p/go-buffer-pool" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ) var log = logging.Logger("ping") diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/handshake.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/handshake.go index 65fe294bd..6e119cb59 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/handshake.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/handshake.go @@ -10,17 +10,14 @@ import ( "runtime/debug" "time" - "github.com/minio/sha256-simd" - "golang.org/x/crypto/chacha20poly1305" - + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/security/noise/pb" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/flynn/noise" "github.com/gogo/protobuf/proto" pool "github.com/libp2p/go-buffer-pool" + "github.com/minio/sha256-simd" ) // payloadSigPrefix is prepended to our Noise static key before signing with @@ -57,6 +54,7 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) { Pattern: noise.HandshakeXX, Initiator: s.initiator, StaticKeypair: kp, + Prologue: s.prologue, } hs, err := noise.NewHandshakeState(cfg) @@ -64,11 +62,6 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) { return fmt.Errorf("error initializing handshake state: %w", err) } - payload, err := s.generateHandshakePayload(kp) - if err != nil { - return err - } - // set a deadline to complete the handshake, if one has been supplied. // clear it after we're done. if deadline, ok := ctx.Deadline(); ok { @@ -78,20 +71,14 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) { } } - // We can re-use this buffer for all handshake messages as its size - // will be the size of the maximum handshake message for the Noise XX pattern. - // Also, since we prefix every noise handshake message with its length, we need to account for - // it when we fetch the buffer from the pool - maxMsgSize := 2*noise.DH25519.DHLen() + len(payload) + 2*chacha20poly1305.Overhead - hbuf := pool.Get(maxMsgSize + LengthPrefixLength) + // We can re-use this buffer for all handshake messages. + hbuf := pool.Get(2 << 10) defer pool.Put(hbuf) if s.initiator { // stage 0 // - // do not send the payload just yet, as it would be plaintext; not secret. // Handshake Msg Len = len(DH ephemeral key) - err = s.sendHandshakeMessage(hs, nil, hbuf) - if err != nil { + if err := s.sendHandshakeMessage(hs, nil, hbuf); err != nil { return fmt.Errorf("error sending handshake message: %w", err) } @@ -100,20 +87,32 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) { if err != nil { return fmt.Errorf("error reading handshake message: %w", err) } - err = s.handleRemoteHandshakePayload(plaintext, hs.PeerStatic()) + rcvdEd, err := s.handleRemoteHandshakePayload(plaintext, hs.PeerStatic()) if err != nil { return err } + if s.initiatorEarlyDataHandler != nil { + if err := s.initiatorEarlyDataHandler.Received(ctx, s.insecureConn, rcvdEd); err != nil { + return err + } + } // stage 2 // // Handshake Msg Len = len(DHT static key) + MAC(static key is encrypted) + len(Payload) + MAC(payload is encrypted) - err = s.sendHandshakeMessage(hs, payload, hbuf) + var ed *pb.NoiseExtensions + if s.initiatorEarlyDataHandler != nil { + ed = s.initiatorEarlyDataHandler.Send(ctx, s.insecureConn, s.remoteID) + } + payload, err := s.generateHandshakePayload(kp, ed) if err != nil { + return err + } + if err := s.sendHandshakeMessage(hs, payload, hbuf); err != nil { return fmt.Errorf("error sending handshake message: %w", err) } + return nil } else { // stage 0 // - // We don't expect any payload on the first message. if _, err := s.readHandshakeMessage(hs); err != nil { return fmt.Errorf("error reading handshake message: %w", err) } @@ -121,8 +120,15 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) { // stage 1 // // Handshake Msg Len = len(DH ephemeral key) + len(DHT static key) + MAC(static key is encrypted) + len(Payload) + // MAC(payload is encrypted) - err = s.sendHandshakeMessage(hs, payload, hbuf) + var ed *pb.NoiseExtensions + if s.responderEarlyDataHandler != nil { + ed = s.responderEarlyDataHandler.Send(ctx, s.insecureConn, s.remoteID) + } + payload, err := s.generateHandshakePayload(kp, ed) if err != nil { + return err + } + if err := s.sendHandshakeMessage(hs, payload, hbuf); err != nil { return fmt.Errorf("error sending handshake message: %w", err) } @@ -131,13 +137,17 @@ func (s *secureSession) runHandshake(ctx context.Context) (err error) { if err != nil { return fmt.Errorf("error reading handshake message: %w", err) } - err = s.handleRemoteHandshakePayload(plaintext, hs.PeerStatic()) + rcvdEd, err := s.handleRemoteHandshakePayload(plaintext, hs.PeerStatic()) if err != nil { return err } + if s.responderEarlyDataHandler != nil { + if err := s.responderEarlyDataHandler.Received(ctx, s.insecureConn, rcvdEd); err != nil { + return err + } + } + return nil } - - return nil } // setCipherStates sets the initial cipher states that will be used to protect @@ -214,8 +224,8 @@ func (s *secureSession) readHandshakeMessage(hs *noise.HandshakeState) ([]byte, // generateHandshakePayload creates a libp2p handshake payload with a // signature of our static noise key. -func (s *secureSession) generateHandshakePayload(localStatic noise.DHKey) ([]byte, error) { - // obtain the public key from the handshake session so we can sign it with +func (s *secureSession) generateHandshakePayload(localStatic noise.DHKey, ext *pb.NoiseExtensions) ([]byte, error) { + // obtain the public key from the handshake session, so we can sign it with // our libp2p secret key. localKeyRaw, err := crypto.MarshalPublicKey(s.LocalPublicKey()) if err != nil { @@ -230,10 +240,11 @@ func (s *secureSession) generateHandshakePayload(localStatic noise.DHKey) ([]byt } // create payload - payload := new(pb.NoiseHandshakePayload) - payload.IdentityKey = localKeyRaw - payload.IdentitySig = signedPayload - payloadEnc, err := proto.Marshal(payload) + payloadEnc, err := proto.Marshal(&pb.NoiseHandshakePayload{ + IdentityKey: localKeyRaw, + IdentitySig: signedPayload, + Extensions: ext, + }) if err != nil { return nil, fmt.Errorf("error marshaling handshake payload: %w", err) } @@ -242,22 +253,23 @@ func (s *secureSession) generateHandshakePayload(localStatic noise.DHKey) ([]byt // handleRemoteHandshakePayload unmarshals the handshake payload object sent // by the remote peer and validates the signature against the peer's static Noise key. -func (s *secureSession) handleRemoteHandshakePayload(payload []byte, remoteStatic []byte) error { +// It returns the data attached to the payload. +func (s *secureSession) handleRemoteHandshakePayload(payload []byte, remoteStatic []byte) (*pb.NoiseExtensions, error) { // unmarshal payload nhp := new(pb.NoiseHandshakePayload) err := proto.Unmarshal(payload, nhp) if err != nil { - return fmt.Errorf("error unmarshaling remote handshake payload: %w", err) + return nil, fmt.Errorf("error unmarshaling remote handshake payload: %w", err) } // unpack remote peer's public libp2p key remotePubKey, err := crypto.UnmarshalPublicKey(nhp.GetIdentityKey()) if err != nil { - return err + return nil, err } id, err := peer.IDFromPublicKey(remotePubKey) if err != nil { - return err + return nil, err } // check the peer ID for: @@ -265,7 +277,7 @@ func (s *secureSession) handleRemoteHandshakePayload(payload []byte, remoteStati // * inbound connections, if we know which peer we want to connect to (SecureInbound called with a peer ID) if (s.initiator && s.remoteID != id) || (!s.initiator && s.remoteID != "" && s.remoteID != id) { // use Pretty() as it produces the full b58-encoded string, rather than abbreviated forms. - return fmt.Errorf("peer id mismatch: expected %s, but remote key matches %s", s.remoteID.Pretty(), id.Pretty()) + return nil, fmt.Errorf("peer id mismatch: expected %s, but remote key matches %s", s.remoteID.Pretty(), id.Pretty()) } // verify payload is signed by asserted remote libp2p key. @@ -273,13 +285,13 @@ func (s *secureSession) handleRemoteHandshakePayload(payload []byte, remoteStati msg := append([]byte(payloadSigPrefix), remoteStatic...) ok, err := remotePubKey.Verify(msg, sig) if err != nil { - return fmt.Errorf("error verifying signature: %w", err) + return nil, fmt.Errorf("error verifying signature: %w", err) } else if !ok { - return fmt.Errorf("handshake signature invalid") + return nil, fmt.Errorf("handshake signature invalid") } // set remote peer key and id s.remoteID = id s.remoteKey = remotePubKey - return nil + return nhp.Extensions, nil } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.pb.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.pb.go index ffb29c3c8..84db783ef 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.pb.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.pb.go @@ -22,17 +22,61 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +type NoiseExtensions struct { + WebtransportCerthashes [][]byte `protobuf:"bytes,1,rep,name=webtransport_certhashes,json=webtransportCerthashes" json:"webtransport_certhashes,omitempty"` +} + +func (m *NoiseExtensions) Reset() { *m = NoiseExtensions{} } +func (m *NoiseExtensions) String() string { return proto.CompactTextString(m) } +func (*NoiseExtensions) ProtoMessage() {} +func (*NoiseExtensions) Descriptor() ([]byte, []int) { + return fileDescriptor_678c914f1bee6d56, []int{0} +} +func (m *NoiseExtensions) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NoiseExtensions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_NoiseExtensions.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *NoiseExtensions) XXX_Merge(src proto.Message) { + xxx_messageInfo_NoiseExtensions.Merge(m, src) +} +func (m *NoiseExtensions) XXX_Size() int { + return m.Size() +} +func (m *NoiseExtensions) XXX_DiscardUnknown() { + xxx_messageInfo_NoiseExtensions.DiscardUnknown(m) +} + +var xxx_messageInfo_NoiseExtensions proto.InternalMessageInfo + +func (m *NoiseExtensions) GetWebtransportCerthashes() [][]byte { + if m != nil { + return m.WebtransportCerthashes + } + return nil +} + type NoiseHandshakePayload struct { - IdentityKey []byte `protobuf:"bytes,1,opt,name=identity_key,json=identityKey,proto3" json:"identity_key,omitempty"` - IdentitySig []byte `protobuf:"bytes,2,opt,name=identity_sig,json=identitySig,proto3" json:"identity_sig,omitempty"` - Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + IdentityKey []byte `protobuf:"bytes,1,opt,name=identity_key,json=identityKey" json:"identity_key"` + IdentitySig []byte `protobuf:"bytes,2,opt,name=identity_sig,json=identitySig" json:"identity_sig"` + Extensions *NoiseExtensions `protobuf:"bytes,4,opt,name=extensions" json:"extensions,omitempty"` } func (m *NoiseHandshakePayload) Reset() { *m = NoiseHandshakePayload{} } func (m *NoiseHandshakePayload) String() string { return proto.CompactTextString(m) } func (*NoiseHandshakePayload) ProtoMessage() {} func (*NoiseHandshakePayload) Descriptor() ([]byte, []int) { - return fileDescriptor_678c914f1bee6d56, []int{0} + return fileDescriptor_678c914f1bee6d56, []int{1} } func (m *NoiseHandshakePayload) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,31 +119,68 @@ func (m *NoiseHandshakePayload) GetIdentitySig() []byte { return nil } -func (m *NoiseHandshakePayload) GetData() []byte { +func (m *NoiseHandshakePayload) GetExtensions() *NoiseExtensions { if m != nil { - return m.Data + return m.Extensions } return nil } func init() { + proto.RegisterType((*NoiseExtensions)(nil), "pb.NoiseExtensions") proto.RegisterType((*NoiseHandshakePayload)(nil), "pb.NoiseHandshakePayload") } func init() { proto.RegisterFile("payload.proto", fileDescriptor_678c914f1bee6d56) } var fileDescriptor_678c914f1bee6d56 = []byte{ - // 152 bytes of a gzipped FileDescriptorProto + // 221 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2d, 0x48, 0xac, 0xcc, - 0xc9, 0x4f, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2a, 0x48, 0x52, 0x2a, 0xe4, - 0x12, 0xf5, 0xcb, 0xcf, 0x2c, 0x4e, 0xf5, 0x48, 0xcc, 0x4b, 0x29, 0xce, 0x48, 0xcc, 0x4e, 0x0d, - 0x80, 0x28, 0x11, 0x52, 0xe4, 0xe2, 0xc9, 0x4c, 0x49, 0xcd, 0x2b, 0xc9, 0x2c, 0xa9, 0x8c, 0xcf, - 0x4e, 0xad, 0x94, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x09, 0xe2, 0x86, 0x89, 0x79, 0xa7, 0x56, 0xa2, - 0x28, 0x29, 0xce, 0x4c, 0x97, 0x60, 0x42, 0x55, 0x12, 0x9c, 0x99, 0x2e, 0x24, 0xc4, 0xc5, 0x92, - 0x92, 0x58, 0x92, 0x28, 0xc1, 0x0c, 0x96, 0x02, 0xb3, 0x9d, 0x24, 0x4e, 0x3c, 0x92, 0x63, 0xbc, - 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96, 0x63, - 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x89, 0x0d, 0xec, 0x2e, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x51, 0x37, 0xd7, 0x40, 0xa8, 0x00, 0x00, 0x00, + 0xc9, 0x4f, 0x4c, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2a, 0x48, 0x52, 0xf2, 0xe2, + 0xe2, 0xf7, 0xcb, 0xcf, 0x2c, 0x4e, 0x75, 0xad, 0x28, 0x49, 0xcd, 0x2b, 0xce, 0xcc, 0xcf, 0x2b, + 0x16, 0x32, 0xe7, 0x12, 0x2f, 0x4f, 0x4d, 0x2a, 0x29, 0x4a, 0xcc, 0x2b, 0x2e, 0xc8, 0x2f, 0x2a, + 0x89, 0x4f, 0x4e, 0x2d, 0x2a, 0xc9, 0x48, 0x2c, 0xce, 0x48, 0x2d, 0x96, 0x60, 0x54, 0x60, 0xd6, + 0xe0, 0x09, 0x12, 0x43, 0x96, 0x76, 0x86, 0xcb, 0x2a, 0xcd, 0x63, 0xe4, 0x12, 0x05, 0x1b, 0xe6, + 0x91, 0x98, 0x97, 0x52, 0x9c, 0x91, 0x98, 0x9d, 0x1a, 0x00, 0xb1, 0x4f, 0x48, 0x9d, 0x8b, 0x27, + 0x33, 0x25, 0x35, 0xaf, 0x24, 0xb3, 0xa4, 0x32, 0x3e, 0x3b, 0xb5, 0x52, 0x82, 0x51, 0x81, 0x51, + 0x83, 0xc7, 0x89, 0xe5, 0xc4, 0x3d, 0x79, 0x86, 0x20, 0x6e, 0x98, 0x8c, 0x77, 0x6a, 0x25, 0x8a, + 0xc2, 0xe2, 0xcc, 0x74, 0x09, 0x26, 0x6c, 0x0a, 0x83, 0x33, 0xd3, 0x85, 0x8c, 0xb9, 0xb8, 0x52, + 0xe1, 0x4e, 0x96, 0x60, 0x51, 0x60, 0xd4, 0xe0, 0x36, 0x12, 0xd6, 0x2b, 0x48, 0xd2, 0x43, 0xf3, + 0x4d, 0x10, 0x92, 0x32, 0x27, 0x89, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, + 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x00, + 0x04, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xb0, 0x39, 0x45, 0x1a, 0x01, 0x00, 0x00, +} + +func (m *NoiseExtensions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NoiseExtensions) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NoiseExtensions) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.WebtransportCerthashes) > 0 { + for iNdEx := len(m.WebtransportCerthashes) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.WebtransportCerthashes[iNdEx]) + copy(dAtA[i:], m.WebtransportCerthashes[iNdEx]) + i = encodeVarintPayload(dAtA, i, uint64(len(m.WebtransportCerthashes[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil } func (m *NoiseHandshakePayload) Marshal() (dAtA []byte, err error) { @@ -122,21 +203,26 @@ func (m *NoiseHandshakePayload) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Data) > 0 { - i -= len(m.Data) - copy(dAtA[i:], m.Data) - i = encodeVarintPayload(dAtA, i, uint64(len(m.Data))) + if m.Extensions != nil { + { + size, err := m.Extensions.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPayload(dAtA, i, uint64(size)) + } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } - if len(m.IdentitySig) > 0 { + if m.IdentitySig != nil { i -= len(m.IdentitySig) copy(dAtA[i:], m.IdentitySig) i = encodeVarintPayload(dAtA, i, uint64(len(m.IdentitySig))) i-- dAtA[i] = 0x12 } - if len(m.IdentityKey) > 0 { + if m.IdentityKey != nil { i -= len(m.IdentityKey) copy(dAtA[i:], m.IdentityKey) i = encodeVarintPayload(dAtA, i, uint64(len(m.IdentityKey))) @@ -157,22 +243,37 @@ func encodeVarintPayload(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *NoiseExtensions) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.WebtransportCerthashes) > 0 { + for _, b := range m.WebtransportCerthashes { + l = len(b) + n += 1 + l + sovPayload(uint64(l)) + } + } + return n +} + func (m *NoiseHandshakePayload) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.IdentityKey) - if l > 0 { + if m.IdentityKey != nil { + l = len(m.IdentityKey) n += 1 + l + sovPayload(uint64(l)) } - l = len(m.IdentitySig) - if l > 0 { + if m.IdentitySig != nil { + l = len(m.IdentitySig) n += 1 + l + sovPayload(uint64(l)) } - l = len(m.Data) - if l > 0 { + if m.Extensions != nil { + l = m.Extensions.Size() n += 1 + l + sovPayload(uint64(l)) } return n @@ -184,6 +285,88 @@ func sovPayload(x uint64) (n int) { func sozPayload(x uint64) (n int) { return sovPayload(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } +func (m *NoiseExtensions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NoiseExtensions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NoiseExtensions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field WebtransportCerthashes", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPayload + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthPayload + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthPayload + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.WebtransportCerthashes = append(m.WebtransportCerthashes, make([]byte, postIndex-iNdEx)) + copy(m.WebtransportCerthashes[len(m.WebtransportCerthashes)-1], dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPayload(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPayload + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NoiseHandshakePayload) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -281,11 +464,11 @@ func (m *NoiseHandshakePayload) Unmarshal(dAtA []byte) error { m.IdentitySig = []byte{} } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Extensions", wireType) } - var byteLen int + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowPayload @@ -295,24 +478,26 @@ func (m *NoiseHandshakePayload) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { + if msglen < 0 { return ErrInvalidLengthPayload } - postIndex := iNdEx + byteLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthPayload } if postIndex > l { return io.ErrUnexpectedEOF } - m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) - if m.Data == nil { - m.Data = []byte{} + if m.Extensions == nil { + m.Extensions = &NoiseExtensions{} + } + if err := m.Extensions.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err } iNdEx = postIndex default: diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.proto b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.proto index 05a78c6f3..7c1b0bdca 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.proto +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/pb/payload.proto @@ -1,8 +1,12 @@ -syntax = "proto3"; +syntax = "proto2"; package pb; -message NoiseHandshakePayload { - bytes identity_key = 1; - bytes identity_sig = 2; - bytes data = 3; +message NoiseExtensions { + repeated bytes webtransport_certhashes = 1; +} + +message NoiseHandshakePayload { + optional bytes identity_key = 1; + optional bytes identity_sig = 2; + optional NoiseExtensions extensions = 4; } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session.go index 9675cc03b..692c9174a 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session.go @@ -9,8 +9,8 @@ import ( "github.com/flynn/noise" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ) type secureSession struct { @@ -34,18 +34,26 @@ type secureSession struct { enc *noise.CipherState dec *noise.CipherState + + // noise prologue + prologue []byte + + initiatorEarlyDataHandler, responderEarlyDataHandler EarlyDataHandler } // newSecureSession creates a Noise session over the given insecureConn Conn, using // the libp2p identity keypair from the given Transport. -func newSecureSession(tpt *Transport, ctx context.Context, insecure net.Conn, remote peer.ID, initiator bool) (*secureSession, error) { +func newSecureSession(tpt *Transport, ctx context.Context, insecure net.Conn, remote peer.ID, prologue []byte, initiatorEDH, responderEDH EarlyDataHandler, initiator bool) (*secureSession, error) { s := &secureSession{ - insecureConn: insecure, - insecureReader: bufio.NewReader(insecure), - initiator: initiator, - localID: tpt.localID, - localKey: tpt.privateKey, - remoteID: remote, + insecureConn: insecure, + insecureReader: bufio.NewReader(insecure), + initiator: initiator, + localID: tpt.localID, + localKey: tpt.privateKey, + remoteID: remote, + prologue: prologue, + initiatorEarlyDataHandler: initiatorEDH, + responderEarlyDataHandler: responderEDH, } // the go-routine we create to run the handshake will diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session_transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session_transport.go new file mode 100644 index 000000000..7b468edbb --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/session_transport.go @@ -0,0 +1,81 @@ +package noise + +import ( + "context" + "net" + + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + "github.com/libp2p/go-libp2p/p2p/security/noise/pb" + + manet "github.com/multiformats/go-multiaddr/net" +) + +type SessionOption = func(*SessionTransport) error + +// Prologue sets a prologue for the Noise session. +// The handshake will only complete successfully if both parties set the same prologue. +// See https://noiseprotocol.org/noise.html#prologue for details. +func Prologue(prologue []byte) SessionOption { + return func(s *SessionTransport) error { + s.prologue = prologue + return nil + } +} + +// EarlyDataHandler defines what the application payload is for either the second +// (if responder) or third (if initiator) handshake message, and defines the +// logic for handling the other side's early data. Note the early data in the +// second handshake message is encrypted, but the peer is not authenticated at that point. +type EarlyDataHandler interface { + // Send for the initiator is called for the client before sending the third + // handshake message. Defines the application payload for the third message. + // Send for the responder is called before sending the second handshake message. + Send(context.Context, net.Conn, peer.ID) *pb.NoiseExtensions + // Received for the initiator is called when the second handshake message + // from the responder is received. + // Received for the responder is called when the third handshake message + // from the initiator is received. + Received(context.Context, net.Conn, *pb.NoiseExtensions) error +} + +// EarlyData sets the `EarlyDataHandler` for the initiator and responder roles. +// See `EarlyDataHandler` for more details. +func EarlyData(initiator, responder EarlyDataHandler) SessionOption { + return func(s *SessionTransport) error { + s.initiatorEarlyDataHandler = initiator + s.responderEarlyDataHandler = responder + return nil + } +} + +var _ sec.SecureTransport = &SessionTransport{} + +// SessionTransport can be used +// to provide per-connection options +type SessionTransport struct { + t *Transport + // options + prologue []byte + + initiatorEarlyDataHandler, responderEarlyDataHandler EarlyDataHandler +} + +// SecureInbound runs the Noise handshake as the responder. +// If p is empty, connections from any peer are accepted. +func (i *SessionTransport) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + c, err := newSecureSession(i.t, ctx, insecure, p, i.prologue, i.initiatorEarlyDataHandler, i.responderEarlyDataHandler, false) + if err != nil { + addr, maErr := manet.FromNetAddr(insecure.RemoteAddr()) + if maErr == nil { + canonicallog.LogPeerStatus(100, p, addr, "handshake_failure", "noise", "err", err.Error()) + } + } + return c, err +} + +// SecureOutbound runs the Noise handshake as the initiator. +func (i *SessionTransport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { + return newSecureSession(i.t, ctx, insecure, p, i.prologue, i.initiatorEarlyDataHandler, i.responderEarlyDataHandler, true) +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/transport.go index c39da8697..c6923698c 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/noise/transport.go @@ -4,10 +4,11 @@ import ( "context" "net" - "github.com/libp2p/go-libp2p-core/canonicallog" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/canonicallog" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + manet "github.com/multiformats/go-multiaddr/net" ) @@ -17,7 +18,7 @@ const ID = "/noise" var _ sec.SecureTransport = &Transport{} // Transport implements the interface sec.SecureTransport -// https://godoc.org/github.com/libp2p/go-libp2p-core/sec#SecureConn +// https://godoc.org/github.com/libp2p/go-libp2p/core/sec#SecureConn type Transport struct { localID peer.ID privateKey crypto.PrivKey @@ -40,7 +41,7 @@ func New(privkey crypto.PrivKey) (*Transport, error) { // SecureInbound runs the Noise handshake as the responder. // If p is empty, connections from any peer are accepted. func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { - c, err := newSecureSession(t, ctx, insecure, p, false) + c, err := newSecureSession(t, ctx, insecure, p, nil, nil, nil, false) if err != nil { addr, maErr := manet.FromNetAddr(insecure.RemoteAddr()) if maErr == nil { @@ -52,5 +53,15 @@ func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn, p peer // SecureOutbound runs the Noise handshake as the initiator. func (t *Transport) SecureOutbound(ctx context.Context, insecure net.Conn, p peer.ID) (sec.SecureConn, error) { - return newSecureSession(t, ctx, insecure, p, true) + return newSecureSession(t, ctx, insecure, p, nil, nil, nil, true) +} + +func (t *Transport) WithSessionOptions(opts ...SessionOption) (sec.SecureTransport, error) { + st := &SessionTransport{t: t} + for _, opt := range opts { + if err := opt(st); err != nil { + return nil, err + } + } + return st, nil } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/conn.go index cf32fa459..6353eac80 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/conn.go @@ -3,9 +3,9 @@ package libp2ptls import ( "crypto/tls" - ci "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + ci "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" ) type conn struct { diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/crypto.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/crypto.go index 24a06939e..aa16b334f 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/crypto.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/crypto.go @@ -1,6 +1,7 @@ package libp2ptls import ( + "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" @@ -17,8 +18,8 @@ import ( "golang.org/x/sys/cpu" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ) const certValidityPeriod = 100 * 365 * 24 * time.Hour // ~100 years @@ -38,9 +39,37 @@ type Identity struct { config tls.Config } +// IdentityConfig is used to configure an Identity +type IdentityConfig struct { + CertTemplate *x509.Certificate +} + +// IdentityOption transforms an IdentityConfig to apply optional settings. +type IdentityOption func(r *IdentityConfig) + +// WithCertTemplate specifies the template to use when generating a new certificate. +func WithCertTemplate(template *x509.Certificate) IdentityOption { + return func(c *IdentityConfig) { + c.CertTemplate = template + } +} + // NewIdentity creates a new identity -func NewIdentity(privKey ic.PrivKey) (*Identity, error) { - cert, err := keyToCertificate(privKey) +func NewIdentity(privKey ic.PrivKey, opts ...IdentityOption) (*Identity, error) { + config := IdentityConfig{} + for _, opt := range opts { + opt(&config) + } + + var err error + if config.CertTemplate == nil { + config.CertTemplate, err = certTemplate() + if err != nil { + return nil, err + } + } + + cert, err := keyToCertificate(privKey, config.CertTemplate) if err != nil { return nil, err } @@ -167,54 +196,50 @@ func PubKeyFromCertChain(chain []*x509.Certificate) (ic.PubKey, error) { return pubKey, nil } -func keyToCertificate(sk ic.PrivKey) (*tls.Certificate, error) { - certKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, err - } - +// GenerateSignedExtension uses the provided private key to sign the public key, and returns the +// signature within a pkix.Extension. +// This extension is included in a certificate to cryptographically tie it to the libp2p private key. +func GenerateSignedExtension(sk ic.PrivKey, pubKey crypto.PublicKey) (pkix.Extension, error) { keyBytes, err := ic.MarshalPublicKey(sk.GetPublic()) if err != nil { - return nil, err + return pkix.Extension{}, err } - certKeyPub, err := x509.MarshalPKIXPublicKey(certKey.Public()) + certKeyPub, err := x509.MarshalPKIXPublicKey(pubKey) if err != nil { - return nil, err + return pkix.Extension{}, err } signature, err := sk.Sign(append([]byte(certificatePrefix), certKeyPub...)) if err != nil { - return nil, err + return pkix.Extension{}, err } value, err := asn1.Marshal(signedKey{ PubKey: keyBytes, Signature: signature, }) + if err != nil { + return pkix.Extension{}, err + } + + return pkix.Extension{Id: extensionID, Critical: extensionCritical, Value: value}, nil +} + +// keyToCertificate generates a new ECDSA private key and corresponding x509 certificate. +// The certificate includes an extension that cryptographically ties it to the provided libp2p +// private key to authenticate TLS connections. +func keyToCertificate(sk ic.PrivKey, certTmpl *x509.Certificate) (*tls.Certificate, error) { + certKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return nil, err } - bigNum := big.NewInt(1 << 62) - sn, err := rand.Int(rand.Reader, bigNum) + // after calling CreateCertificate, these will end up in Certificate.Extensions + extension, err := GenerateSignedExtension(sk, certKey.Public()) if err != nil { return nil, err } - subjectSN, err := rand.Int(rand.Reader, bigNum) - if err != nil { - return nil, err - } - tmpl := &x509.Certificate{ - SerialNumber: sn, - NotBefore: time.Now().Add(-time.Hour), - NotAfter: time.Now().Add(certValidityPeriod), - // According to RFC 3280, the issuer field must be set, - // see https://datatracker.ietf.org/doc/html/rfc3280#section-4.1.2.4. - Subject: pkix.Name{SerialNumber: subjectSN.String()}, - // after calling CreateCertificate, these will end up in Certificate.Extensions - ExtraExtensions: []pkix.Extension{ - {Id: extensionID, Critical: extensionCritical, Value: value}, - }, - } - certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, certKey.Public(), certKey) + certTmpl.ExtraExtensions = append(certTmpl.ExtraExtensions, extension) + + certDER, err := x509.CreateCertificate(rand.Reader, certTmpl, certTmpl, certKey.Public(), certKey) if err != nil { return nil, err } @@ -224,12 +249,35 @@ func keyToCertificate(sk ic.PrivKey) (*tls.Certificate, error) { }, nil } +// certTemplate returns the template for generating an Identity's TLS certificates. +func certTemplate() (*x509.Certificate, error) { + bigNum := big.NewInt(1 << 62) + sn, err := rand.Int(rand.Reader, bigNum) + if err != nil { + return nil, err + } + + subjectSN, err := rand.Int(rand.Reader, bigNum) + if err != nil { + return nil, err + } + + return &x509.Certificate{ + SerialNumber: sn, + NotBefore: time.Now().Add(-time.Hour), + NotAfter: time.Now().Add(certValidityPeriod), + // According to RFC 3280, the issuer field must be set, + // see https://datatracker.ietf.org/doc/html/rfc3280#section-4.1.2.4. + Subject: pkix.Name{SerialNumber: subjectSN.String()}, + }, nil +} + // We want nodes without AES hardware (e.g. ARM) support to always use ChaCha. // Only if both nodes have AES hardware support (e.g. x86), AES should be used. // x86->x86: AES, ARM->x86: ChaCha, x86->ARM: ChaCha and ARM->ARM: Chacha // This function returns true if we don't have AES hardware support, and false otherwise. // Thus, ARM servers will always use their own cipher suite preferences (ChaCha first), -// and x86 servers will aways use the client's cipher suite preferences. +// and x86 servers will always use the client's cipher suite preferences. func preferServerCipherSuites() bool { // Copied from the Go TLS implementation. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/transport.go index 90c714911..f6aa64f6a 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/security/tls/transport.go @@ -9,10 +9,11 @@ import ( "os" "runtime/debug" - "github.com/libp2p/go-libp2p-core/canonicallog" - ci "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/sec" + "github.com/libp2p/go-libp2p/core/canonicallog" + ci "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/sec" + manet "github.com/multiformats/go-multiaddr/net" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/conn.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/conn.go index 778460c6c..a012dea3d 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/conn.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/conn.go @@ -2,19 +2,28 @@ package libp2pquic import ( "context" + "net" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - tpt "github.com/libp2p/go-libp2p-core/transport" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + tpt "github.com/libp2p/go-libp2p/core/transport" "github.com/lucas-clemente/quic-go" ma "github.com/multiformats/go-multiaddr" ) +type pConn interface { + net.PacketConn + + // count conn reference + DecreaseCount() + IncreaseCount() +} + type conn struct { quicConn quic.Connection - pconn *reuseConn + pconn pConn transport *transport scope network.ConnManagementScope diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/listener.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/listener.go index 955c0f6c0..949a3e7db 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/listener.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/listener.go @@ -5,13 +5,12 @@ import ( "crypto/tls" "net" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + tpt "github.com/libp2p/go-libp2p/core/transport" p2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - tpt "github.com/libp2p/go-libp2p-core/transport" - "github.com/lucas-clemente/quic-go" ma "github.com/multiformats/go-multiaddr" ) @@ -21,7 +20,7 @@ var quicListen = quic.Listen // so we can mock it in tests // A listener listens for QUIC connections. type listener struct { quicListener quic.Listener - conn *reuseConn + conn pConn transport *transport rcmgr network.ResourceManager privKey ic.PrivKey @@ -31,7 +30,7 @@ type listener struct { var _ tpt.Listener = &listener{} -func newListener(rconn *reuseConn, t *transport, localPeer peer.ID, key ic.PrivKey, identity *p2ptls.Identity, rcmgr network.ResourceManager) (tpt.Listener, error) { +func newListener(pconn pConn, t *transport, localPeer peer.ID, key ic.PrivKey, identity *p2ptls.Identity, rcmgr network.ResourceManager) (tpt.Listener, error) { var tlsConf tls.Config tlsConf.GetConfigForClient = func(_ *tls.ClientHelloInfo) (*tls.Config, error) { // return a tls.Config that verifies the peer's certificate chain. @@ -41,7 +40,7 @@ func newListener(rconn *reuseConn, t *transport, localPeer peer.ID, key ic.PrivK conf, _ := identity.ConfigForPeer("") return conf, nil } - ln, err := quicListen(rconn, &tlsConf, t.serverConfig) + ln, err := quicListen(pconn, &tlsConf, t.serverConfig) if err != nil { return nil, err } @@ -50,7 +49,7 @@ func newListener(rconn *reuseConn, t *transport, localPeer peer.ID, key ic.PrivK return nil, err } return &listener{ - conn: rconn, + conn: pconn, quicListener: ln, transport: t, rcmgr: rcmgr, @@ -146,7 +145,17 @@ func (l *listener) setupConn(qconn quic.Connection) (*conn, error) { // Close closes the listener. func (l *listener) Close() error { defer l.conn.DecreaseCount() - return l.quicListener.Close() + + if err := l.quicListener.Close(); err != nil { + return err + } + + if _, ok := l.conn.(*noreuseConn); ok { + // if we use a `noreuseConn`, close the underlying connection + return l.conn.Close() + } + + return nil } // Addr returns the address of this listener. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/options.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/options.go new file mode 100644 index 000000000..75b2dbca0 --- /dev/null +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/options.go @@ -0,0 +1,33 @@ +package libp2pquic + +type Option func(opts *config) error + +type config struct { + disableReuseport bool + metrics bool +} + +func (cfg *config) apply(opts ...Option) error { + for _, opt := range opts { + if err := opt(cfg); err != nil { + return err + } + } + + return nil +} + +func DisableReuseport() Option { + return func(cfg *config) error { + cfg.disableReuseport = true + return nil + } +} + +// WithMetrics enables Prometheus metrics collection. +func WithMetrics() Option { + return func(cfg *config) error { + cfg.metrics = true + return nil + } +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/stream.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/stream.go index 883b0cc34..5d276dab8 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/stream.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/stream.go @@ -3,7 +3,7 @@ package libp2pquic import ( "errors" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/network" "github.com/lucas-clemente/quic-go" ) diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer.go index c5bbf7149..50f429dca 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer.go @@ -13,16 +13,12 @@ import ( "github.com/lucas-clemente/quic-go/qlog" ) -var tracer logging.Tracer +var qlogTracer logging.Tracer func init() { - tracers := []logging.Tracer{&metricsTracer{}} if qlogDir := os.Getenv("QLOGDIR"); len(qlogDir) > 0 { - if qlogger := initQlogger(qlogDir); qlogger != nil { - tracers = append(tracers, qlogger) - } + qlogTracer = initQlogger(qlogDir) } - tracer = logging.NewMultiplexedTracer(tracers...) } func initQlogger(qlogDir string) logging.Tracer { @@ -62,7 +58,9 @@ func newQlogger(qlogDir string, role logging.Perspective, connID []byte) io.Writ return &qlogger{ f: f, filename: finalFilename, - Writer: bufio.NewWriter(f), + // The size of a qlog file for a raw file download is ~2/3 of the amount of data transferred. + // bufio.NewWriter creates a buffer with a buffer of only 4 kB, leading to a large number of syscalls. + Writer: bufio.NewWriterSize(f, 128<<10), } } @@ -80,7 +78,7 @@ func (l *qlogger) Close() error { return err } defer f.Close() - buf := bufio.NewWriter(f) + buf := bufio.NewWriterSize(f, 128<<10) c, err := zstd.NewWriter(buf, zstd.WithEncoderLevel(zstd.SpeedFastest), zstd.WithWindowSize(32*1024)) if err != nil { return err diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer_metrics.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer_metrics.go index cbf2701fe..624139fc1 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer_metrics.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/tracer_metrics.go @@ -167,7 +167,9 @@ func init() { prometheus.MustRegister(collector) } -type metricsTracer struct{} +type metricsTracer struct { + logging.NullTracer +} var _ logging.Tracer = &metricsTracer{} @@ -179,10 +181,9 @@ func (m *metricsTracer) SentPacket(_ net.Addr, _ *logging.Header, size logging.B bytesTransferred.WithLabelValues("sent").Add(float64(size)) } -func (m *metricsTracer) DroppedPacket(addr net.Addr, packetType logging.PacketType, count logging.ByteCount, reason logging.PacketDropReason) { -} - type metricsConnTracer struct { + logging.NullConnectionTracer + perspective logging.Perspective startTime time.Time connID logging.ConnectionID @@ -224,9 +225,6 @@ func (m *metricsConnTracer) StartedConnection(net.Addr, net.Addr, logging.Connec collector.AddConn(m.connID.String(), m) } -func (m *metricsConnTracer) NegotiatedVersion(chosen quic.VersionNumber, clientVersions []quic.VersionNumber, serverVersions []quic.VersionNumber) { -} - func (m *metricsConnTracer) ClosedConnection(e error) { var ( applicationErr *quic.ApplicationError @@ -264,9 +262,6 @@ func (m *metricsConnTracer) ClosedConnection(e error) { } connErrors.WithLabelValues(side, desc).Inc() } -func (m *metricsConnTracer) SentTransportParameters(parameters *logging.TransportParameters) {} -func (m *metricsConnTracer) ReceivedTransportParameters(parameters *logging.TransportParameters) {} -func (m *metricsConnTracer) RestoredTransportParameters(parameters *logging.TransportParameters) {} func (m *metricsConnTracer) SentPacket(hdr *logging.ExtendedHeader, size logging.ByteCount, _ *logging.AckFrame, _ []logging.Frame) { bytesTransferred.WithLabelValues("sent").Add(float64(size)) sentPackets.WithLabelValues(m.getEncLevel(logging.PacketTypeFromHeader(&hdr.Header))).Inc() @@ -329,8 +324,6 @@ func (m *metricsConnTracer) UpdatedMetrics(rttStats *logging.RTTStats, cwnd, byt m.mutex.Unlock() } -func (m *metricsConnTracer) AcknowledgedPacket(logging.EncryptionLevel, logging.PacketNumber) {} - func (m *metricsConnTracer) LostPacket(level logging.EncryptionLevel, _ logging.PacketNumber, r logging.PacketLossReason) { var reason string switch r { @@ -344,23 +337,11 @@ func (m *metricsConnTracer) LostPacket(level logging.EncryptionLevel, _ logging. lostPackets.WithLabelValues(level.String(), reason).Inc() } -func (m *metricsConnTracer) UpdatedCongestionState(state logging.CongestionState) {} -func (m *metricsConnTracer) UpdatedPTOCount(value uint32) {} -func (m *metricsConnTracer) UpdatedKeyFromTLS(level logging.EncryptionLevel, perspective logging.Perspective) { -} -func (m *metricsConnTracer) UpdatedKey(generation logging.KeyPhase, remote bool) {} func (m *metricsConnTracer) DroppedEncryptionLevel(level logging.EncryptionLevel) { if level == logging.EncryptionHandshake { m.handleHandshakeComplete() } } -func (m *metricsConnTracer) DroppedKey(generation logging.KeyPhase) {} -func (m *metricsConnTracer) SetLossTimer(timerType logging.TimerType, level logging.EncryptionLevel, time time.Time) { -} - -func (m *metricsConnTracer) LossTimerExpired(timerType logging.TimerType, level logging.EncryptionLevel) { -} -func (m *metricsConnTracer) LossTimerCanceled() {} func (m *metricsConnTracer) Close() { if m.handshakeComplete { @@ -371,8 +352,6 @@ func (m *metricsConnTracer) Close() { collector.RemoveConn(m.connID.String()) } -func (m *metricsConnTracer) Debug(name, msg string) {} - func (m *metricsConnTracer) handleHandshakeComplete() { m.handshakeComplete = true newConns.WithLabelValues(m.getDirection(), "true").Inc() diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/transport.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/transport.go index cee7b1374..0b908db43 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/transport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/quic/transport.go @@ -12,21 +12,21 @@ import ( "golang.org/x/crypto/hkdf" + "github.com/libp2p/go-libp2p/core/connmgr" + ic "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/pnet" + tpt "github.com/libp2p/go-libp2p/core/transport" p2ptls "github.com/libp2p/go-libp2p/p2p/security/tls" - "github.com/libp2p/go-libp2p-core/connmgr" - ic "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/pnet" - tpt "github.com/libp2p/go-libp2p-core/transport" - ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" manet "github.com/multiformats/go-multiaddr/net" logging "github.com/ipfs/go-log/v2" "github.com/lucas-clemente/quic-go" + quiclogging "github.com/lucas-clemente/quic-go/logging" "github.com/minio/sha256-simd" ) @@ -43,9 +43,9 @@ var quicConfig = &quic.Config{ MaxIncomingUniStreams: -1, // disable unidirectional streams MaxStreamReceiveWindow: 10 * (1 << 20), // 10 MB MaxConnectionReceiveWindow: 15 * (1 << 20), // 15 MB - AcceptToken: func(clientAddr net.Addr, _ *quic.Token) bool { - // TODO(#6): require source address validation when under load - return true + RequireAddressValidation: func(net.Addr) bool { + // TODO(#1535): require source address validation when under load + return false }, KeepAlivePeriod: 15 * time.Second, Versions: []quic.VersionNumber{quic.VersionDraft29, quic.Version1}, @@ -54,18 +54,26 @@ var quicConfig = &quic.Config{ const statelessResetKeyInfo = "libp2p quic stateless reset key" const errorCodeConnectionGating = 0x47415445 // GATE in ASCII -type connManager struct { - reuseUDP4 *reuse - reuseUDP6 *reuse +type noreuseConn struct { + *net.UDPConn } -func newConnManager() (*connManager, error) { +func (c *noreuseConn) IncreaseCount() {} +func (c *noreuseConn) DecreaseCount() {} + +type connManager struct { + reuseUDP4 *reuse + reuseUDP6 *reuse + reuseportEnable bool +} + +func newConnManager(reuseport bool) (*connManager, error) { reuseUDP4 := newReuse() reuseUDP6 := newReuse() - return &connManager{ - reuseUDP4: reuseUDP4, - reuseUDP6: reuseUDP6, + reuseUDP4: reuseUDP4, + reuseUDP6: reuseUDP6, + reuseportEnable: reuseport, }, nil } @@ -80,20 +88,43 @@ func (c *connManager) getReuse(network string) (*reuse, error) { } } -func (c *connManager) Listen(network string, laddr *net.UDPAddr) (*reuseConn, error) { - reuse, err := c.getReuse(network) +func (c *connManager) Listen(network string, laddr *net.UDPAddr) (pConn, error) { + if c.reuseportEnable { + reuse, err := c.getReuse(network) + if err != nil { + return nil, err + } + return reuse.Listen(network, laddr) + } + + conn, err := net.ListenUDP(network, laddr) if err != nil { return nil, err } - return reuse.Listen(network, laddr) + return &noreuseConn{conn}, nil } -func (c *connManager) Dial(network string, raddr *net.UDPAddr) (*reuseConn, error) { - reuse, err := c.getReuse(network) +func (c *connManager) Dial(network string, raddr *net.UDPAddr) (pConn, error) { + if c.reuseportEnable { + reuse, err := c.getReuse(network) + if err != nil { + return nil, err + } + return reuse.Dial(network, raddr) + } + + var laddr *net.UDPAddr + switch network { + case "udp4": + laddr = &net.UDPAddr{IP: net.IPv4zero, Port: 0} + case "udp6": + laddr = &net.UDPAddr{IP: net.IPv6zero, Port: 0} + } + conn, err := net.ListenUDP(network, laddr) if err != nil { return nil, err } - return reuse.Dial(network, raddr) + return &noreuseConn{conn}, nil } func (c *connManager) Close() error { @@ -134,7 +165,12 @@ type activeHolePunch struct { } // NewTransport creates a new QUIC transport -func NewTransport(key ic.PrivKey, psk pnet.PSK, gater connmgr.ConnectionGater, rcmgr network.ResourceManager) (tpt.Transport, error) { +func NewTransport(key ic.PrivKey, psk pnet.PSK, gater connmgr.ConnectionGater, rcmgr network.ResourceManager, opts ...Option) (tpt.Transport, error) { + var cfg config + if err := cfg.apply(opts...); err != nil { + return nil, fmt.Errorf("unable to apply quic-tpt option(s): %w", err) + } + if len(psk) > 0 { log.Error("QUIC doesn't support private networks yet.") return nil, errors.New("QUIC doesn't support private networks yet") @@ -147,24 +183,33 @@ func NewTransport(key ic.PrivKey, psk pnet.PSK, gater connmgr.ConnectionGater, r if err != nil { return nil, err } - connManager, err := newConnManager() + connManager, err := newConnManager(!cfg.disableReuseport) if err != nil { return nil, err } if rcmgr == nil { rcmgr = network.NullResourceManager } - config := quicConfig.Clone() + qconfig := quicConfig.Clone() keyBytes, err := key.Raw() if err != nil { return nil, err } keyReader := hkdf.New(sha256.New, keyBytes, nil, []byte(statelessResetKeyInfo)) - config.StatelessResetKey = make([]byte, 32) - if _, err := io.ReadFull(keyReader, config.StatelessResetKey); err != nil { + qconfig.StatelessResetKey = make([]byte, 32) + if _, err := io.ReadFull(keyReader, qconfig.StatelessResetKey); err != nil { return nil, err } - config.Tracer = tracer + var tracers []quiclogging.Tracer + if qlogTracer != nil { + tracers = append(tracers, qlogTracer) + } + if cfg.metrics { + tracers = append(tracers, &metricsTracer{}) + } + if len(tracers) > 0 { + qconfig.Tracer = quiclogging.NewMultiplexedTracer(tracers...) + } tr := &transport{ privKey: key, @@ -176,9 +221,9 @@ func NewTransport(key ic.PrivKey, psk pnet.PSK, gater connmgr.ConnectionGater, r conns: make(map[quic.Connection]*conn), holePunching: make(map[holePunchKey]*activeHolePunch), } - config.AllowConnectionWindowIncrease = tr.allowWindowIncrease - tr.serverConfig = config - tr.clientConfig = config.Clone() + qconfig.AllowConnectionWindowIncrease = tr.allowWindowIncrease + tr.serverConfig = qconfig + tr.clientConfig = qconfig.Clone() return tr, nil } @@ -305,7 +350,7 @@ loop: punchErr = err break } - if _, err := pconn.UDPConn.WriteToUDP(payload, addr); err != nil { + if _, err := pconn.WriteTo(payload, addr); err != nil { punchErr = err break } @@ -370,6 +415,9 @@ func (t *transport) Listen(addr ma.Multiaddr) (tpt.Listener, error) { } ln, err := newListener(conn, t, t.localPeer, t.privKey, t.identity, t.rcmgr) if err != nil { + if !t.connManager.reuseportEnable { + conn.Close() + } conn.DecreaseCount() return nil, err } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics.go index c3b6c7d9f..0ae24801a 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package tcp diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_darwin.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_darwin.go index f0015f405..32cc0288d 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_darwin.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_darwin.go @@ -1,5 +1,4 @@ //go:build darwin -// +build darwin package tcp diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_general.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_general.go index 36b3d648c..6b6728344 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_general.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_general.go @@ -1,5 +1,4 @@ //go:build !linux && !darwin && !windows -// +build !linux,!darwin,!windows package tcp diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_linux.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_linux.go index 046faa51c..b73d300d9 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_linux.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package tcp diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_windows.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_windows.go index c80cf6fae..7142e7dbe 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_windows.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/metrics_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package tcp diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/reuseport.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/reuseport.go index c40d2ebe2..ba0930462 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/reuseport.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/reuseport.go @@ -26,7 +26,7 @@ func init() { // is here because we want to be able to turn reuseport on and off selectively. // For now we use an ENV variable, as this handles our pressing need: // -// LIBP2P_TCP_REUSEPORT=false ipfs daemon +// LIBP2P_TCP_REUSEPORT=false ipfs daemon // // If this becomes a sought after feature, we could add this to the config. // In the end, reuseport is a stop-gap. diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/tcp.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/tcp.go index 120feee8d..61bb38e23 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/tcp.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/tcp/tcp.go @@ -9,12 +9,11 @@ import ( "syscall" "time" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" "github.com/libp2p/go-libp2p/p2p/net/reuseport" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" - logging "github.com/ipfs/go-log/v2" ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" @@ -107,14 +106,21 @@ func WithConnectionTimeout(d time.Duration) Option { } } +func WithMetrics() Option { + return func(tr *TcpTransport) error { + tr.enableMetrics = true + return nil + } +} + // TcpTransport is the TCP transport. type TcpTransport struct { // Connection upgrader for upgrading insecure stream connections to // secure multiplex connections. upgrader transport.Upgrader - // Explicitly disable reuseport. - disableReuseport bool + disableReuseport bool // Explicitly disable reuseport. + enableMetrics bool // TCP connect timeout connectTimeout time.Duration @@ -190,10 +196,14 @@ func (t *TcpTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) // This means we can immediately reuse the 5-tuple and reconnect. tryLinger(conn, 0) tryKeepAlive(conn, true) - c, err := newTracingConn(conn, true) - if err != nil { - connScope.Done() - return nil, err + c := conn + if t.enableMetrics { + var err error + c, err = newTracingConn(conn, true) + if err != nil { + connScope.Done() + return nil, err + } } direction := network.DirOutbound if ok, isClient, _ := network.GetSimultaneousConnect(ctx); ok && !isClient { @@ -220,7 +230,9 @@ func (t *TcpTransport) Listen(laddr ma.Multiaddr) (transport.Listener, error) { if err != nil { return nil, err } - list = newTracingListener(&tcpListener{list, 0}) + if t.enableMetrics { + list = newTracingListener(&tcpListener{list, 0}) + } return t.upgrader.UpgradeListener(t, list), nil } diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/addrs.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/addrs.go index 608eb2d0d..5fea8567b 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/addrs.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/addrs.go @@ -105,23 +105,17 @@ func ParseWebsocketNetAddr(a net.Addr) (ma.Multiaddr, error) { } func parseMultiaddr(maddr ma.Multiaddr) (*url.URL, error) { - // Only look at the _last_ component. - maddr, wscomponent := ma.SplitLast(maddr) - if maddr == nil || wscomponent == nil { - return nil, fmt.Errorf("websocket addrs need at least two components") + parsed, err := parseWebsocketMultiaddr(maddr) + if err != nil { + return nil, err } - var scheme string - switch wscomponent.Protocol().Code { - case ma.P_WS: - scheme = "ws" - case ma.P_WSS: + scheme := "ws" + if parsed.isWSS { scheme = "wss" - default: - return nil, fmt.Errorf("not a websocket multiaddr") } - network, host, err := manet.DialArgs(maddr) + network, host, err := manet.DialArgs(parsed.restMultiaddr) if err != nil { return nil, err } @@ -135,3 +129,47 @@ func parseMultiaddr(maddr ma.Multiaddr) (*url.URL, error) { Host: host, }, nil } + +type parsedWebsocketMultiaddr struct { + isWSS bool + // sni is the SNI value for the TLS handshake, and for setting HTTP Host header + sni *ma.Component + // the rest of the multiaddr before the /tls/sni/example.com/ws or /ws or /wss + restMultiaddr ma.Multiaddr +} + +func parseWebsocketMultiaddr(a ma.Multiaddr) (parsedWebsocketMultiaddr, error) { + out := parsedWebsocketMultiaddr{} + // First check if we have a WSS component. If so we'll canonicalize it into a /tls/ws + withoutWss := a.Decapsulate(wssComponent) + if !withoutWss.Equal(a) { + a = withoutWss.Encapsulate(tlsWsComponent) + } + + // Remove the ws component + withoutWs := a.Decapsulate(wsComponent) + if withoutWs.Equal(a) { + return out, fmt.Errorf("not a websocket multiaddr") + } + + rest := withoutWs + // If this is not a wss then withoutWs is the rest of the multiaddr + out.restMultiaddr = withoutWs + for { + var head *ma.Component + rest, head = ma.SplitLast(rest) + if head == nil || rest == nil { + break + } + + if head.Protocol().Code == ma.P_SNI { + out.sni = head + } else if head.Protocol().Code == ma.P_TLS { + out.isWSS = true + out.restMultiaddr = rest + break + } + } + + return out, nil +} diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/listener.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/listener.go index b94bed798..128fdf5eb 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/listener.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/listener.go @@ -10,11 +10,6 @@ import ( manet "github.com/multiformats/go-multiaddr/net" ) -var ( - wsma = ma.StringCast("/ws") - wssma = ma.StringCast("/wss") -) - type listener struct { nl net.Listener server http.Server @@ -25,16 +20,31 @@ type listener struct { incoming chan *Conn } +func (pwma *parsedWebsocketMultiaddr) toMultiaddr() ma.Multiaddr { + if !pwma.isWSS { + return pwma.restMultiaddr.Encapsulate(wsComponent) + } + + if pwma.sni == nil { + return pwma.restMultiaddr.Encapsulate(tlsComponent).Encapsulate(wsComponent) + } + + return pwma.restMultiaddr.Encapsulate(tlsComponent).Encapsulate(pwma.sni).Encapsulate(wsComponent) +} + // newListener creates a new listener from a raw net.Listener. // tlsConf may be nil (for unencrypted websockets). func newListener(a ma.Multiaddr, tlsConf *tls.Config) (*listener, error) { - // Only look at the _last_ component. - maddr, wscomponent := ma.SplitLast(a) - isWSS := wscomponent.Equal(wssma) - if isWSS && tlsConf == nil { + parsed, err := parseWebsocketMultiaddr(a) + if err != nil { + return nil, err + } + + if parsed.isWSS && tlsConf == nil { return nil, fmt.Errorf("cannot listen on wss address %s without a tls.Config", a) } - lnet, lnaddr, err := manet.DialArgs(maddr) + + lnet, lnaddr, err := manet.DialArgs(parsed.restMultiaddr) if err != nil { return nil, err } @@ -54,15 +64,16 @@ func newListener(a ma.Multiaddr, tlsConf *tls.Config) (*listener, error) { _, last := ma.SplitFirst(laddr) laddr = first.Encapsulate(last) } + parsed.restMultiaddr = laddr ln := &listener{ nl: nl, - laddr: laddr.Encapsulate(wscomponent), + laddr: parsed.toMultiaddr(), incoming: make(chan *Conn), closed: make(chan struct{}), } ln.server = http.Server{Handler: ln} - if isWSS { + if parsed.isWSS { ln.server.TLSConfig = tlsConf } return ln, nil diff --git a/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/websocket.go b/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/websocket.go index af74ccfbf..f1294a570 100644 --- a/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/websocket.go +++ b/vendor/github.com/libp2p/go-libp2p/p2p/transport/websocket/websocket.go @@ -4,12 +4,13 @@ package websocket import ( "context" "crypto/tls" + "net" "net/http" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/transport" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/transport" ma "github.com/multiformats/go-multiaddr" mafmt "github.com/multiformats/go-multiaddr-fmt" @@ -21,9 +22,27 @@ import ( // WsFmt is multiaddr formatter for WsProtocol var WsFmt = mafmt.And(mafmt.TCP, mafmt.Base(ma.P_WS)) -// This is _not_ WsFmt because we want the transport to stick to dialing fully -// resolved addresses. -var dialMatcher = mafmt.And(mafmt.Or(mafmt.IP, mafmt.DNS), mafmt.Base(ma.P_TCP), mafmt.Or(mafmt.Base(ma.P_WS), mafmt.Base(ma.P_WSS))) +var dialMatcher = mafmt.And( + mafmt.Or(mafmt.IP, mafmt.DNS), + mafmt.Base(ma.P_TCP), + mafmt.Or( + mafmt.Base(ma.P_WS), + mafmt.And( + mafmt.Or( + mafmt.And( + mafmt.Base(ma.P_TLS), + mafmt.Base(ma.P_SNI)), + mafmt.Base(ma.P_TLS), + ), + mafmt.Base(ma.P_WS)), + mafmt.Base(ma.P_WSS))) + +var ( + wssComponent = ma.StringCast("/wss") + tlsWsComponent = ma.StringCast("/tls/ws") + tlsComponent = ma.StringCast("/tls") + wsComponent = ma.StringCast("/ws") +) func init() { manet.RegisterFromNetAddr(ParseWebsocketNetAddr, "websocket") @@ -77,8 +96,9 @@ func New(u transport.Upgrader, rcmgr network.ResourceManager, opts ...Option) (* rcmgr = network.NullResourceManager } t := &WebsocketTransport{ - upgrader: u, - rcmgr: rcmgr, + upgrader: u, + rcmgr: rcmgr, + tlsClientConf: &tls.Config{}, } for _, opt := range opts { if err := opt(t); err != nil { @@ -100,6 +120,42 @@ func (t *WebsocketTransport) Proxy() bool { return false } +func (t *WebsocketTransport) Resolve(ctx context.Context, maddr ma.Multiaddr) ([]ma.Multiaddr, error) { + parsed, err := parseWebsocketMultiaddr(maddr) + if err != nil { + return nil, err + } + + if !parsed.isWSS { + // No /tls/ws component, this isn't a secure websocket multiaddr. We can just return it here + return []ma.Multiaddr{maddr}, nil + } + + if parsed.sni == nil { + var err error + // We don't have an sni component, we'll use dns/dnsaddr + ma.ForEach(parsed.restMultiaddr, func(c ma.Component) bool { + switch c.Protocol().Code { + case ma.P_DNS, ma.P_DNS4, ma.P_DNS6, ma.P_DNSADDR: + // err shouldn't happen since this means we couldn't parse a dns hostname for an sni value. + parsed.sni, err = ma.NewComponent("sni", c.Value()) + return false + } + return true + }) + if err != nil { + return nil, err + } + } + + if parsed.sni == nil { + // we didn't find anything to set the sni with. So we just return the given multiaddr + return []ma.Multiaddr{maddr}, nil + } + + return []ma.Multiaddr{parsed.toMultiaddr()}, nil +} + func (t *WebsocketTransport) Dial(ctx context.Context, raddr ma.Multiaddr, p peer.ID) (transport.CapableConn, error) { connScope, err := t.rcmgr.OpenConnection(network.DirOutbound, true, raddr) if err != nil { @@ -121,9 +177,32 @@ func (t *WebsocketTransport) maDial(ctx context.Context, raddr ma.Multiaddr) (ma isWss := wsurl.Scheme == "wss" dialer := ws.Dialer{HandshakeTimeout: 30 * time.Second} if isWss { - dialer.TLSClientConfig = t.tlsClientConf + sni := "" + sni, err = raddr.ValueForProtocol(ma.P_SNI) + if err != nil { + sni = "" + } + if sni != "" { + copytlsClientConf := t.tlsClientConf.Clone() + copytlsClientConf.ServerName = sni + dialer.TLSClientConfig = copytlsClientConf + ipAddr := wsurl.Host + // Setting the NetDial because we already have the resolved IP address, so we don't want to do another resolution. + // We set the `.Host` to the sni field so that the host header gets properly set. + dialer.NetDial = func(network, address string) (net.Conn, error) { + tcpAddr, err := net.ResolveTCPAddr(network, ipAddr) + if err != nil { + return nil, err + } + return net.DialTCP("tcp", nil, tcpAddr) + } + wsurl.Host = sni + ":" + wsurl.Port() + } else { + dialer.TLSClientConfig = t.tlsClientConf + } } + wscon, _, err := dialer.DialContext(ctx, wsurl.String(), nil) if err != nil { return nil, err diff --git a/vendor/github.com/libp2p/go-libp2p/version.json b/vendor/github.com/libp2p/go-libp2p/version.json index c6a304fe7..8ab9c1fa7 100644 --- a/vendor/github.com/libp2p/go-libp2p/version.json +++ b/vendor/github.com/libp2p/go-libp2p/version.json @@ -1,3 +1,3 @@ { - "version": "v0.21.0" + "version": "v0.23.3" } diff --git a/vendor/github.com/libp2p/go-openssl/alloc.go b/vendor/github.com/libp2p/go-openssl/alloc.go new file mode 100644 index 000000000..25d064a2f --- /dev/null +++ b/vendor/github.com/libp2p/go-openssl/alloc.go @@ -0,0 +1,19 @@ +package openssl + +// #include "shim.h" +import "C" + +import ( + "unsafe" + + "github.com/mattn/go-pointer" +) + +//export go_ssl_crypto_ex_free +func go_ssl_crypto_ex_free( + parent *C.void, ptr unsafe.Pointer, + cryptoData *C.CRYPTO_EX_DATA, idx C.int, + argl C.long, argp *C.void, +) { + pointer.Unref(ptr) +} diff --git a/vendor/github.com/libp2p/go-openssl/bio.go b/vendor/github.com/libp2p/go-openssl/bio.go index 9fe32aa80..caf2b37a7 100644 --- a/vendor/github.com/libp2p/go-openssl/bio.go +++ b/vendor/github.com/libp2p/go-openssl/bio.go @@ -112,14 +112,14 @@ func writeBioPending(b *C.BIO) C.long { return C.long(len(ptr.buf)) } -func (b *writeBio) WriteTo(w io.Writer) (rv int64, err error) { - b.op_mtx.Lock() - defer b.op_mtx.Unlock() +func (wb *writeBio) WriteTo(w io.Writer) (rv int64, err error) { + wb.op_mtx.Lock() + defer wb.op_mtx.Unlock() // write whatever data we currently have - b.data_mtx.Lock() - data := b.buf - b.data_mtx.Unlock() + wb.data_mtx.Lock() + data := wb.buf + wb.data_mtx.Unlock() if len(data) == 0 { return 0, nil @@ -127,26 +127,26 @@ func (b *writeBio) WriteTo(w io.Writer) (rv int64, err error) { n, err := w.Write(data) // subtract however much data we wrote from the buffer - b.data_mtx.Lock() - b.buf = b.buf[:copy(b.buf, b.buf[n:])] - if b.release_buffers && len(b.buf) == 0 { - b.buf = nil + wb.data_mtx.Lock() + wb.buf = wb.buf[:copy(wb.buf, wb.buf[n:])] + if wb.release_buffers && len(wb.buf) == 0 { + wb.buf = nil } - b.data_mtx.Unlock() + wb.data_mtx.Unlock() return int64(n), err } -func (self *writeBio) Disconnect(b *C.BIO) { - if loadWritePtr(b) == self { +func (wb *writeBio) Disconnect(b *C.BIO) { + if loadWritePtr(b) == wb { writeBioMapping.Del(token(C.X_BIO_get_data(b))) C.X_BIO_set_data(b, nil) } } -func (b *writeBio) MakeCBIO() *C.BIO { +func (wb *writeBio) MakeCBIO() *C.BIO { rv := C.X_BIO_new_write_bio() - token := writeBioMapping.Add(unsafe.Pointer(b)) + token := writeBioMapping.Add(unsafe.Pointer(wb)) C.X_BIO_set_data(rv, unsafe.Pointer(token)) return rv } @@ -228,53 +228,53 @@ func readBioPending(b *C.BIO) C.long { return C.long(len(ptr.buf)) } -func (b *readBio) ReadFromOnce(r io.Reader) (n int, err error) { - b.op_mtx.Lock() - defer b.op_mtx.Unlock() +func (rb *readBio) ReadFromOnce(r io.Reader) (n int, err error) { + rb.op_mtx.Lock() + defer rb.op_mtx.Unlock() // make sure we have a destination that fits at least one SSL record - b.data_mtx.Lock() - if cap(b.buf) < len(b.buf)+SSLRecordSize { - new_buf := make([]byte, len(b.buf), len(b.buf)+SSLRecordSize) - copy(new_buf, b.buf) - b.buf = new_buf + rb.data_mtx.Lock() + if cap(rb.buf) < len(rb.buf)+SSLRecordSize { + new_buf := make([]byte, len(rb.buf), len(rb.buf)+SSLRecordSize) + copy(new_buf, rb.buf) + rb.buf = new_buf } - dst := b.buf[len(b.buf):cap(b.buf)] - dst_slice := b.buf - b.data_mtx.Unlock() + dst := rb.buf[len(rb.buf):cap(rb.buf)] + dst_slice := rb.buf + rb.data_mtx.Unlock() n, err = r.Read(dst) - b.data_mtx.Lock() - defer b.data_mtx.Unlock() + rb.data_mtx.Lock() + defer rb.data_mtx.Unlock() if n > 0 { - if len(dst_slice) != len(b.buf) { + if len(dst_slice) != len(rb.buf) { // someone shrunk the buffer, so we read in too far ahead and we // need to slide backwards - copy(b.buf[len(b.buf):len(b.buf)+n], dst) + copy(rb.buf[len(rb.buf):len(rb.buf)+n], dst) } - b.buf = b.buf[:len(b.buf)+n] + rb.buf = rb.buf[:len(rb.buf)+n] } return n, err } -func (b *readBio) MakeCBIO() *C.BIO { +func (rb *readBio) MakeCBIO() *C.BIO { rv := C.X_BIO_new_read_bio() - token := readBioMapping.Add(unsafe.Pointer(b)) + token := readBioMapping.Add(unsafe.Pointer(rb)) C.X_BIO_set_data(rv, unsafe.Pointer(token)) return rv } -func (self *readBio) Disconnect(b *C.BIO) { - if loadReadPtr(b) == self { +func (rb *readBio) Disconnect(b *C.BIO) { + if loadReadPtr(b) == rb { readBioMapping.Del(token(C.X_BIO_get_data(b))) C.X_BIO_set_data(b, nil) } } -func (b *readBio) MarkEOF() { - b.data_mtx.Lock() - defer b.data_mtx.Unlock() - b.eof = true +func (rb *readBio) MarkEOF() { + rb.data_mtx.Lock() + defer rb.data_mtx.Unlock() + rb.eof = true } type anyBio C.BIO diff --git a/vendor/github.com/libp2p/go-openssl/build.go b/vendor/github.com/libp2p/go-openssl/build.go index d3f19d82a..990fbb4b2 100644 --- a/vendor/github.com/libp2p/go-openssl/build.go +++ b/vendor/github.com/libp2p/go-openssl/build.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !openssl_static // +build !openssl_static package openssl diff --git a/vendor/github.com/libp2p/go-openssl/build_static.go b/vendor/github.com/libp2p/go-openssl/build_static.go index 69fad0a4f..dde544618 100644 --- a/vendor/github.com/libp2p/go-openssl/build_static.go +++ b/vendor/github.com/libp2p/go-openssl/build_static.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build openssl_static // +build openssl_static package openssl diff --git a/vendor/github.com/libp2p/go-openssl/cert.go b/vendor/github.com/libp2p/go-openssl/cert.go index 82dfc3697..97c788f7c 100644 --- a/vendor/github.com/libp2p/go-openssl/cert.go +++ b/vendor/github.com/libp2p/go-openssl/cert.go @@ -267,8 +267,8 @@ func (c *Certificate) Sign(privKey PrivateKey, digest EVP_MD) error { case EVP_SHA384: case EVP_SHA512: default: - return errors.New("Unsupported digest" + - "You're probably looking for 'EVP_SHA256' or 'EVP_SHA512'.") + return errors.New("unsupported digest; " + + "you're probably looking for 'EVP_SHA256' or 'EVP_SHA512'") } return c.insecureSign(privKey, digest) } @@ -336,7 +336,7 @@ func (c *Certificate) AddCustomExtension(nid NID, value []byte) error { val := (*C.char)(C.CBytes(value)) defer C.free(unsafe.Pointer(val)) if int(C.add_custom_ext(c.x, C.int(nid), val, C.int(len(value)))) == 0 { - return errors.New("Unable to add extension") + return errors.New("unable to add extension") } return nil } diff --git a/vendor/github.com/libp2p/go-openssl/ciphers.go b/vendor/github.com/libp2p/go-openssl/ciphers.go index 509bf6410..a3a597c45 100644 --- a/vendor/github.com/libp2p/go-openssl/ciphers.go +++ b/vendor/github.com/libp2p/go-openssl/ciphers.go @@ -125,7 +125,7 @@ func (ctx *cipherCtx) applyKeyAndIV(key, iv []byte) error { } else { res = C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, kptr, iptr) } - if 1 != res { + if res != 1 { return errors.New("failed to apply key/IV") } } @@ -243,7 +243,7 @@ func newEncryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( if e != nil { eptr = e.e } - if 1 != C.EVP_EncryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { + if C.EVP_EncryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) != 1 { return nil, errors.New("failed to initialize cipher context") } err = ctx.applyKeyAndIV(key, iv) @@ -266,7 +266,7 @@ func newDecryptionCipherCtx(c *Cipher, e *Engine, key, iv []byte) ( if e != nil { eptr = e.e } - if 1 != C.EVP_DecryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) { + if C.EVP_DecryptInit_ex(ctx.ctx, c.ptr, eptr, nil, nil) != 1 { return nil, errors.New("failed to initialize cipher context") } err = ctx.applyKeyAndIV(key, iv) @@ -317,7 +317,7 @@ func (ctx *decryptionCipherCtx) DecryptUpdate(input []byte) ([]byte, error) { func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) { outbuf := make([]byte, ctx.BlockSize()) var outlen C.int - if 1 != C.EVP_EncryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { + if C.EVP_EncryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) != 1 { return nil, errors.New("encryption failed") } return outbuf[:outlen], nil @@ -326,7 +326,7 @@ func (ctx *encryptionCipherCtx) EncryptFinal() ([]byte, error) { func (ctx *decryptionCipherCtx) DecryptFinal() ([]byte, error) { outbuf := make([]byte, ctx.BlockSize()) var outlen C.int - if 1 != C.EVP_DecryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) { + if C.EVP_DecryptFinal_ex(ctx.ctx, (*C.uchar)(&outbuf[0]), &outlen) != 1 { // this may mean the tag failed to verify- all previous plaintext // returned must be considered faked and invalid return nil, errors.New("decryption failed") diff --git a/vendor/github.com/libp2p/go-openssl/ciphers_gcm.go b/vendor/github.com/libp2p/go-openssl/ciphers_gcm.go index 7b08e0fd9..06ba0fedb 100644 --- a/vendor/github.com/libp2p/go-openssl/ciphers_gcm.go +++ b/vendor/github.com/libp2p/go-openssl/ciphers_gcm.go @@ -86,8 +86,8 @@ func NewGCMEncryptionCipherCtx(blocksize int, e *Engine, key, iv []byte) ( return nil, fmt.Errorf("could not set IV len to %d: %s", len(iv), err) } - if 1 != C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, nil, - (*C.uchar)(&iv[0])) { + if C.EVP_EncryptInit_ex(ctx.ctx, nil, nil, nil, + (*C.uchar)(&iv[0])) != 1 { return nil, errors.New("failed to apply IV") } } @@ -110,8 +110,8 @@ func NewGCMDecryptionCipherCtx(blocksize int, e *Engine, key, iv []byte) ( return nil, fmt.Errorf("could not set IV len to %d: %s", len(iv), err) } - if 1 != C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, nil, - (*C.uchar)(&iv[0])) { + if C.EVP_DecryptInit_ex(ctx.ctx, nil, nil, nil, + (*C.uchar)(&iv[0])) != 1 { return nil, errors.New("failed to apply IV") } } @@ -123,8 +123,8 @@ func (ctx *authEncryptionCipherCtx) ExtraData(aad []byte) error { return nil } var outlen C.int - if 1 != C.EVP_EncryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), - C.int(len(aad))) { + if C.EVP_EncryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), + C.int(len(aad))) != 1 { return errors.New("failed to add additional authenticated data") } return nil @@ -135,8 +135,8 @@ func (ctx *authDecryptionCipherCtx) ExtraData(aad []byte) error { return nil } var outlen C.int - if 1 != C.EVP_DecryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), - C.int(len(aad))) { + if C.EVP_DecryptUpdate(ctx.ctx, nil, &outlen, (*C.uchar)(&aad[0]), + C.int(len(aad))) != 1 { return errors.New("failed to add additional authenticated data") } return nil diff --git a/vendor/github.com/libp2p/go-openssl/conn.go b/vendor/github.com/libp2p/go-openssl/conn.go index 275803419..fc9421ffc 100644 --- a/vendor/github.com/libp2p/go-openssl/conn.go +++ b/vendor/github.com/libp2p/go-openssl/conn.go @@ -28,13 +28,14 @@ import ( "unsafe" "github.com/libp2p/go-openssl/utils" + "github.com/mattn/go-pointer" ) var ( - zeroReturn = errors.New("zero return") - wantRead = errors.New("want read") - wantWrite = errors.New("want write") - tryAgain = errors.New("try again") + errZeroReturn = errors.New("zero return") + errWantRead = errors.New("want read") + errWantWrite = errors.New("want write") + errTryAgain = errors.New("try again") ) type Conn struct { @@ -137,7 +138,7 @@ func newConn(conn net.Conn, ctx *Ctx) (*Conn, error) { C.SSL_set_bio(ssl, into_ssl_cbio, from_ssl_cbio) s := &SSL{ssl: ssl} - C.SSL_set_ex_data(s.ssl, get_ssl_idx(), unsafe.Pointer(s)) + C.SSL_set_ex_data(s.ssl, get_ssl_idx(), pointer.Save(s)) c := &Conn{ SSL: s, @@ -192,7 +193,7 @@ func (c *Conn) GetCtx() *Ctx { return c.ctx } func (c *Conn) CurrentCipher() (string, error) { p := C.X_SSL_get_cipher_name(c.ssl) if p == nil { - return "", errors.New("Session not established") + return "", errors.New("session not established") } return C.GoString(p), nil @@ -247,7 +248,7 @@ func (c *Conn) getErrorHandler(rv C.int, errno error) func() error { if err != nil { return err } - return tryAgain + return errTryAgain } case C.SSL_ERROR_WANT_WRITE: return func() error { @@ -255,7 +256,7 @@ func (c *Conn) getErrorHandler(rv C.int, errno error) func() error { if err != nil { return err } - return tryAgain + return errTryAgain } case C.SSL_ERROR_SYSCALL: var err error @@ -303,8 +304,8 @@ func (c *Conn) handshake() func() error { // Handshake performs an SSL handshake. If a handshake is not manually // triggered, it will run before the first I/O on the encrypted stream. func (c *Conn) Handshake() error { - err := tryAgain - for err == tryAgain { + err := errTryAgain + for err == errTryAgain { err = c.handleError(c.handshake()) } go c.flushOutputBuffer() @@ -404,15 +405,15 @@ func (c *Conn) shutdown() func() error { } func (c *Conn) shutdownLoop() error { - err := tryAgain + err := errTryAgain shutdown_tries := 0 - for err == tryAgain { + for err == errTryAgain { shutdown_tries = shutdown_tries + 1 err = c.handleError(c.shutdown()) if err == nil { return c.flushOutputBuffer() } - if err == tryAgain && shutdown_tries >= 2 { + if err == errTryAgain && shutdown_tries >= 2 { return errors.New("shutdown requested a third time?") } } @@ -463,8 +464,8 @@ func (c *Conn) Read(b []byte) (n int, err error) { if len(b) == 0 { return 0, nil } - err = tryAgain - for err == tryAgain { + err = errTryAgain + for err == errTryAgain { n, errcb := c.read(b) err = c.handleError(errcb) if err == nil { @@ -504,8 +505,8 @@ func (c *Conn) Write(b []byte) (written int, err error) { if len(b) == 0 { return 0, nil } - err = tryAgain - for err == tryAgain { + err = errTryAgain + for err == errTryAgain { n, errcb := c.write(b) err = c.handleError(errcb) if err == nil { diff --git a/vendor/github.com/libp2p/go-openssl/ctx.go b/vendor/github.com/libp2p/go-openssl/ctx.go index 271defa1b..3bebf0d5c 100644 --- a/vendor/github.com/libp2p/go-openssl/ctx.go +++ b/vendor/github.com/libp2p/go-openssl/ctx.go @@ -27,6 +27,7 @@ import ( "time" "unsafe" + "github.com/mattn/go-pointer" "github.com/spacemonkeygo/spacelog" ) @@ -61,7 +62,7 @@ func newCtx(method *C.SSL_METHOD) (*Ctx, error) { return nil, errorFromErrorQueue() } c := &Ctx{ctx: ctx} - C.SSL_CTX_set_ex_data(ctx, get_ssl_ctx_idx(), unsafe.Pointer(c)) + C.SSL_CTX_set_ex_data(ctx, get_ssl_ctx_idx(), pointer.Save(c)) runtime.SetFinalizer(c, func(c *Ctx) { C.SSL_CTX_free(c.ctx) }) @@ -127,7 +128,7 @@ func NewCtxFromFiles(cert_file string, key_file string) (*Ctx, error) { certs := SplitPEM(cert_bytes) if len(certs) == 0 { - return nil, fmt.Errorf("No PEM certificate found in '%s'", cert_file) + return nil, fmt.Errorf("no PEM certificate found in '%s'", cert_file) } first, certs := certs[0], certs[1:] cert, err := LoadCertificateFromPEM(first) @@ -190,7 +191,7 @@ func (c *Ctx) SetEllipticCurve(curve EllipticCurve) error { k := C.EC_KEY_new_by_curve_name(C.int(curve)) if k == nil { - return errors.New("Unknown curve") + return errors.New("unknown curve") } defer C.EC_KEY_free(k) @@ -302,12 +303,12 @@ type CertificateStoreCtx struct { ssl_ctx *Ctx } -func (self *CertificateStoreCtx) VerifyResult() VerifyResult { - return VerifyResult(C.X509_STORE_CTX_get_error(self.ctx)) +func (csc *CertificateStoreCtx) VerifyResult() VerifyResult { + return VerifyResult(C.X509_STORE_CTX_get_error(csc.ctx)) } -func (self *CertificateStoreCtx) Err() error { - code := C.X509_STORE_CTX_get_error(self.ctx) +func (csc *CertificateStoreCtx) Err() error { + code := C.X509_STORE_CTX_get_error(csc.ctx) if code == C.X509_V_OK { return nil } @@ -315,19 +316,19 @@ func (self *CertificateStoreCtx) Err() error { C.GoString(C.X509_verify_cert_error_string(C.long(code)))) } -func (self *CertificateStoreCtx) Depth() int { - return int(C.X509_STORE_CTX_get_error_depth(self.ctx)) +func (csc *CertificateStoreCtx) Depth() int { + return int(C.X509_STORE_CTX_get_error_depth(csc.ctx)) } -// the certicate returned is only valid for the lifetime of the underlying +// the certificate returned is only valid for the lifetime of the underlying // X509_STORE_CTX -func (self *CertificateStoreCtx) GetCurrentCert() *Certificate { - x509 := C.X509_STORE_CTX_get_current_cert(self.ctx) +func (csc *CertificateStoreCtx) GetCurrentCert() *Certificate { + x509 := C.X509_STORE_CTX_get_current_cert(csc.ctx) if x509 == nil { return nil } // add a ref - if 1 != C.X_X509_add_ref(x509) { + if C.X_X509_add_ref(x509) != 1 { return nil } cert := &Certificate{ @@ -361,6 +362,32 @@ func (c *Ctx) LoadVerifyLocations(ca_file string, ca_path string) error { return nil } +type Version int + +const ( + SSL3_VERSION Version = C.SSL3_VERSION + TLS1_VERSION Version = C.TLS1_VERSION + TLS1_1_VERSION Version = C.TLS1_1_VERSION + TLS1_2_VERSION Version = C.TLS1_2_VERSION + TLS1_3_VERSION Version = C.TLS1_3_VERSION + DTLS1_VERSION Version = C.DTLS1_VERSION + DTLS1_2_VERSION Version = C.DTLS1_2_VERSION +) + +// SetMinProtoVersion sets the minimum supported protocol version for the Ctx. +// http://www.openssl.org/docs/ssl/SSL_CTX_set_min_proto_version.html +func (c *Ctx) SetMinProtoVersion(version Version) bool { + return C.X_SSL_CTX_set_min_proto_version( + c.ctx, C.int(version)) == 1 +} + +// SetMaxProtoVersion sets the maximum supported protocol version for the Ctx. +// http://www.openssl.org/docs/ssl/SSL_CTX_set_max_proto_version.html +func (c *Ctx) SetMaxProtoVersion(version Version) bool { + return C.X_SSL_CTX_set_max_proto_version( + c.ctx, C.int(version)) == 1 +} + type Options int const ( @@ -430,7 +457,7 @@ func go_ssl_ctx_verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CT os.Exit(1) } }() - verify_cb := (*Ctx)(p).verify_cb + verify_cb := pointer.Restore(p).(*Ctx).verify_cb // set up defaults just in case verify_cb is nil if verify_cb != nil { store := &CertificateStoreCtx{ctx: ctx} @@ -531,7 +558,7 @@ func (c *Ctx) SetNextProtos(protos []string) error { for _, proto := range protos { if len(proto) > 255 { return fmt.Errorf( - "Proto length can't be more than 255. But got a proto %s with length %d", + "proto length can't be more than 255. But got a proto %s with length %d", proto, len(proto)) } vector = append(vector, byte(uint8(len(proto)))) @@ -540,7 +567,7 @@ func (c *Ctx) SetNextProtos(protos []string) error { ret := int(C.SSL_CTX_set_alpn_protos(c.ctx, (*C.uchar)(unsafe.Pointer(&vector[0])), C.uint(len(vector)))) if ret != 0 { - return errors.New("Error while setting protos to ctx") + return errors.New("error while setting protos to ctx") } return nil } diff --git a/vendor/github.com/libp2p/go-openssl/fips.go b/vendor/github.com/libp2p/go-openssl/fips.go index f65e14d3e..b15b9bf06 100644 --- a/vendor/github.com/libp2p/go-openssl/fips.go +++ b/vendor/github.com/libp2p/go-openssl/fips.go @@ -16,16 +16,29 @@ package openssl /* #include + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + int FIPS_mode_set(int ONOFF) { + return 0; + } +#endif + */ import "C" +import "errors" import "runtime" // FIPSModeSet enables a FIPS 140-2 validated mode of operation. // https://wiki.openssl.org/index.php/FIPS_mode_set() +// This call has been deleted from OpenSSL 3.0. func FIPSModeSet(mode bool) error { runtime.LockOSThread() defer runtime.UnlockOSThread() + if C.OPENSSL_VERSION_NUMBER >= 0x30000000 { + return errors.New("FIPS_mode_set() has been deleted from OpenSSL 3.0") + } + var r C.int if mode { r = C.FIPS_mode_set(1) diff --git a/vendor/github.com/libp2p/go-openssl/hmac.go b/vendor/github.com/libp2p/go-openssl/hmac.go index a8640cfac..77e8dc58c 100644 --- a/vendor/github.com/libp2p/go-openssl/hmac.go +++ b/vendor/github.com/libp2p/go-openssl/hmac.go @@ -74,7 +74,7 @@ func (h *HMAC) Write(data []byte) (n int, err error) { } func (h *HMAC) Reset() error { - if 1 != C.X_HMAC_Init_ex(h.ctx, nil, 0, nil, nil) { + if C.X_HMAC_Init_ex(h.ctx, nil, 0, nil, nil) != 1 { return errors.New("failed to reset HMAC_CTX") } return nil diff --git a/vendor/github.com/libp2p/go-openssl/hostname.go b/vendor/github.com/libp2p/go-openssl/hostname.go index c92d959e6..9ef4ba293 100644 --- a/vendor/github.com/libp2p/go-openssl/hostname.go +++ b/vendor/github.com/libp2p/go-openssl/hostname.go @@ -17,18 +17,26 @@ package openssl /* #include #include -#include +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + #include + typedef const char x509char; +#else + #include -#ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT -#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 -#define X509_CHECK_FLAG_NO_WILDCARDS 0x2 + #ifndef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT + #define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 + #define X509_CHECK_FLAG_NO_WILDCARDS 0x2 -extern int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags, char **peername); -extern int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags); -extern int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags); + extern int X509_check_host(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags, char **peername); + extern int X509_check_email(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); + extern int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); + typedef const unsigned char x509char; + #else + typedef const char x509char; + #endif #endif */ import "C" @@ -40,7 +48,7 @@ import ( ) var ( - ValidationError = errors.New("Host validation error") + ValidationError = errors.New("host validation error") //lint:ignore ST1012 rename may cause breaking changes; research before renaming. ) type CheckFlags int @@ -59,7 +67,7 @@ func (c *Certificate) CheckHost(host string, flags CheckFlags) error { chost := unsafe.Pointer(C.CString(host)) defer C.free(chost) - rv := C.X509_check_host(c.x, (*C.uchar)(chost), C.size_t(len(host)), + rv := C.X509_check_host(c.x, (*C.x509char)(chost), C.size_t(len(host)), C.uint(flags), nil) if rv > 0 { return nil @@ -78,7 +86,7 @@ func (c *Certificate) CheckHost(host string, flags CheckFlags) error { func (c *Certificate) CheckEmail(email string, flags CheckFlags) error { cemail := unsafe.Pointer(C.CString(email)) defer C.free(cemail) - rv := C.X509_check_email(c.x, (*C.uchar)(cemail), C.size_t(len(email)), + rv := C.X509_check_email(c.x, (*C.x509char)(cemail), C.size_t(len(email)), C.uint(flags)) if rv > 0 { return nil diff --git a/vendor/github.com/libp2p/go-openssl/init.go b/vendor/github.com/libp2p/go-openssl/init.go index 17dc6f387..107adee15 100644 --- a/vendor/github.com/libp2p/go-openssl/init.go +++ b/vendor/github.com/libp2p/go-openssl/init.go @@ -88,14 +88,13 @@ package openssl import "C" import ( - "errors" "fmt" "strings" ) func init() { if rc := C.X_shim_init(); rc != 0 { - panic(fmt.Errorf("X_shim_init failed with %d", rc)) + panic(fmt.Errorf("x_shim_init failed with %d", rc)) } } @@ -113,5 +112,5 @@ func errorFromErrorQueue() error { C.GoString(C.ERR_func_error_string(err)), C.GoString(C.ERR_reason_error_string(err)))) } - return errors.New(fmt.Sprintf("SSL errors: %s", strings.Join(errs, "\n"))) + return fmt.Errorf("SSL errors: %s", strings.Join(errs, "\n")) } diff --git a/vendor/github.com/libp2p/go-openssl/init_posix.go b/vendor/github.com/libp2p/go-openssl/init_posix.go index 605a24bc9..f518d2f83 100644 --- a/vendor/github.com/libp2p/go-openssl/init_posix.go +++ b/vendor/github.com/libp2p/go-openssl/init_posix.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build (linux || darwin || solaris || freebsd || openbsd) && !windows // +build linux darwin solaris freebsd openbsd // +build !windows diff --git a/vendor/github.com/libp2p/go-openssl/init_windows.go b/vendor/github.com/libp2p/go-openssl/init_windows.go index 051133c39..7356b6e2f 100644 --- a/vendor/github.com/libp2p/go-openssl/init_windows.go +++ b/vendor/github.com/libp2p/go-openssl/init_windows.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build windows // +build windows package openssl diff --git a/vendor/github.com/libp2p/go-openssl/key.go b/vendor/github.com/libp2p/go-openssl/key.go index d70bdbbd2..25be635b1 100644 --- a/vendor/github.com/libp2p/go-openssl/key.go +++ b/vendor/github.com/libp2p/go-openssl/key.go @@ -143,36 +143,36 @@ func (key *pKey) SignPKCS1v15(method Method, data []byte) ([]byte, error) { return nil, errors.New("signpkcs1v15: 0-length data or non-null digest") } - if 1 != C.X_EVP_DigestSignInit(ctx, nil, nil, nil, key.key) { + if C.X_EVP_DigestSignInit(ctx, nil, nil, nil, key.key) != 1 { return nil, errors.New("signpkcs1v15: failed to init signature") } // evp signatures are 64 bytes - sig := make([]byte, 64, 64) + sig := make([]byte, 64) var sigblen C.size_t = 64 - if 1 != C.X_EVP_DigestSign(ctx, - ((*C.uchar)(unsafe.Pointer(&sig[0]))), + if C.X_EVP_DigestSign(ctx, + (*C.uchar)(unsafe.Pointer(&sig[0])), &sigblen, (*C.uchar)(unsafe.Pointer(&data[0])), - C.size_t(len(data))) { + C.size_t(len(data))) != 1 { return nil, errors.New("signpkcs1v15: failed to do one-shot signature") } return sig[:sigblen], nil } else { - if 1 != C.X_EVP_SignInit(ctx, method) { + if C.X_EVP_SignInit(ctx, method) != 1 { return nil, errors.New("signpkcs1v15: failed to init signature") } if len(data) > 0 { - if 1 != C.X_EVP_SignUpdate( - ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + if C.X_EVP_SignUpdate( + ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) != 1 { return nil, errors.New("signpkcs1v15: failed to update signature") } } sig := make([]byte, C.X_EVP_PKEY_size(key.key)) var sigblen C.uint - if 1 != C.X_EVP_SignFinal(ctx, - ((*C.uchar)(unsafe.Pointer(&sig[0]))), &sigblen, key.key) { + if C.X_EVP_SignFinal(ctx, + (*C.uchar)(unsafe.Pointer(&sig[0])), &sigblen, key.key) != 1 { return nil, errors.New("signpkcs1v15: failed to finalize signature") } return sig[:sigblen], nil @@ -194,32 +194,32 @@ func (key *pKey) VerifyPKCS1v15(method Method, data, sig []byte) error { return errors.New("verifypkcs1v15: 0-length data or non-null digest") } - if 1 != C.X_EVP_DigestVerifyInit(ctx, nil, nil, nil, key.key) { + if C.X_EVP_DigestVerifyInit(ctx, nil, nil, nil, key.key) != 1 { return errors.New("verifypkcs1v15: failed to init verify") } - if 1 != C.X_EVP_DigestVerify(ctx, - ((*C.uchar)(unsafe.Pointer(&sig[0]))), + if C.X_EVP_DigestVerify(ctx, + (*C.uchar)(unsafe.Pointer(&sig[0])), C.size_t(len(sig)), (*C.uchar)(unsafe.Pointer(&data[0])), - C.size_t(len(data))) { + C.size_t(len(data))) != 1 { return errors.New("verifypkcs1v15: failed to do one-shot verify") } return nil } else { - if 1 != C.X_EVP_VerifyInit(ctx, method) { + if C.X_EVP_VerifyInit(ctx, method) != 1 { return errors.New("verifypkcs1v15: failed to init verify") } if len(data) > 0 { - if 1 != C.X_EVP_VerifyUpdate( - ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) { + if C.X_EVP_VerifyUpdate( + ctx, unsafe.Pointer(&data[0]), C.uint(len(data))) != 1 { return errors.New("verifypkcs1v15: failed to update verify") } } - if 1 != C.X_EVP_VerifyFinal(ctx, - ((*C.uchar)(unsafe.Pointer(&sig[0]))), C.uint(len(sig)), key.key) { + if C.X_EVP_VerifyFinal(ctx, + (*C.uchar)(unsafe.Pointer(&sig[0])), C.uint(len(sig)), key.key) != 1 { return errors.New("verifypkcs1v15: failed to finalize verify") } return nil diff --git a/vendor/github.com/libp2p/go-openssl/md4.go b/vendor/github.com/libp2p/go-openssl/md4.go index e5cc7d867..95d9d2d22 100644 --- a/vendor/github.com/libp2p/go-openssl/md4.go +++ b/vendor/github.com/libp2p/go-openssl/md4.go @@ -51,8 +51,11 @@ func (s *MD4Hash) Close() { } func (s *MD4Hash) Reset() error { - if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md4(), engineRef(s.engine)) { - return errors.New("openssl: md4: cannot init digest ctx") + runtime.LockOSThread() + defer runtime.UnlockOSThread() + if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md4(), engineRef(s.engine)) != 1 { + return errors.New("openssl: md4: cannot init digest ctx: " + + errorFromErrorQueue().Error()) } return nil } @@ -61,16 +64,16 @@ func (s *MD4Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } - if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), - C.size_t(len(p))) { + if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) != 1 { return 0, errors.New("openssl: md4: cannot update digest") } return len(p), nil } func (s *MD4Hash) Sum() (result [16]byte, err error) { - if 1 != C.X_EVP_DigestFinal_ex(s.ctx, - (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + if C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 { return result, errors.New("openssl: md4: cannot finalize ctx") } return result, s.Reset() diff --git a/vendor/github.com/libp2p/go-openssl/md5.go b/vendor/github.com/libp2p/go-openssl/md5.go index 82f2eb2f2..d7e771ee6 100644 --- a/vendor/github.com/libp2p/go-openssl/md5.go +++ b/vendor/github.com/libp2p/go-openssl/md5.go @@ -51,7 +51,7 @@ func (s *MD5Hash) Close() { } func (s *MD5Hash) Reset() error { - if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md5(), engineRef(s.engine)) { + if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_md5(), engineRef(s.engine)) != 1 { return errors.New("openssl: md5: cannot init digest ctx") } return nil @@ -61,16 +61,16 @@ func (s *MD5Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } - if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), - C.size_t(len(p))) { + if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) != 1 { return 0, errors.New("openssl: md5: cannot update digest") } return len(p), nil } func (s *MD5Hash) Sum() (result [16]byte, err error) { - if 1 != C.X_EVP_DigestFinal_ex(s.ctx, - (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + if C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 { return result, errors.New("openssl: md5: cannot finalize ctx") } return result, s.Reset() diff --git a/vendor/github.com/libp2p/go-openssl/net.go b/vendor/github.com/libp2p/go-openssl/net.go index 54beb8ee9..b2293c7c9 100644 --- a/vendor/github.com/libp2p/go-openssl/net.go +++ b/vendor/github.com/libp2p/go-openssl/net.go @@ -17,6 +17,7 @@ package openssl import ( "errors" "net" + "time" ) type listener struct { @@ -80,6 +81,18 @@ func Dial(network, addr string, ctx *Ctx, flags DialFlags) (*Conn, error) { return DialSession(network, addr, ctx, flags, nil) } +// DialTimeout acts like Dial but takes a timeout for network dial. +// +// The timeout includes only network dial. It does not include OpenSSL calls. +// +// See func Dial for a description of the network, addr, ctx and flags +// parameters. +func DialTimeout(network, addr string, timeout time.Duration, ctx *Ctx, + flags DialFlags) (*Conn, error) { + d := net.Dialer{Timeout: timeout} + return dialSession(d, network, addr, ctx, flags, nil) +} + // DialSession will connect to network/address and then wrap the corresponding // underlying connection with an OpenSSL client connection using context ctx. // If flags includes InsecureSkipHostVerification, the server certificate's @@ -95,7 +108,12 @@ func Dial(network, addr string, ctx *Ctx, flags DialFlags) (*Conn, error) { // can be retrieved from the GetSession method on the Conn. func DialSession(network, addr string, ctx *Ctx, flags DialFlags, session []byte) (*Conn, error) { + var d net.Dialer + return dialSession(d, network, addr, ctx, flags, session) +} +func dialSession(d net.Dialer, network, addr string, ctx *Ctx, flags DialFlags, + session []byte) (*Conn, error) { host, _, err := net.SplitHostPort(addr) if err != nil { return nil, err @@ -108,7 +126,8 @@ func DialSession(network, addr string, ctx *Ctx, flags DialFlags, } // TODO: use operating system default certificate chain? } - c, err := net.Dial(network, addr) + + c, err := d.Dial(network, addr) if err != nil { return nil, err } diff --git a/vendor/github.com/libp2p/go-openssl/pem.go b/vendor/github.com/libp2p/go-openssl/pem.go index c8b0c1cf1..6127cf07c 100644 --- a/vendor/github.com/libp2p/go-openssl/pem.go +++ b/vendor/github.com/libp2p/go-openssl/pem.go @@ -19,14 +19,10 @@ import ( ) var pemSplit *regexp.Regexp = regexp.MustCompile(`(?sm)` + - `(^-----[\s-]*?BEGIN.*?-----$` + + `(^-----[\s-]*?BEGIN.*?-----[\s-]*?$` + `.*?` + - `^-----[\s-]*?END.*?-----$)`) + `^-----[\s-]*?END.*?-----[\s-]*?$)`) func SplitPEM(data []byte) [][]byte { - var results [][]byte - for _, block := range pemSplit.FindAll(data, -1) { - results = append(results, block) - } - return results + return pemSplit.FindAll(data, -1) } diff --git a/vendor/github.com/libp2p/go-openssl/sha1.go b/vendor/github.com/libp2p/go-openssl/sha1.go index c227bee84..ab4ad87f1 100644 --- a/vendor/github.com/libp2p/go-openssl/sha1.go +++ b/vendor/github.com/libp2p/go-openssl/sha1.go @@ -58,7 +58,7 @@ func engineRef(e *Engine) *C.ENGINE { } func (s *SHA1Hash) Reset() error { - if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha1(), engineRef(s.engine)) { + if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha1(), engineRef(s.engine)) != 1 { return errors.New("openssl: sha1: cannot init digest ctx") } return nil @@ -68,16 +68,16 @@ func (s *SHA1Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } - if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), - C.size_t(len(p))) { + if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) != 1 { return 0, errors.New("openssl: sha1: cannot update digest") } return len(p), nil } func (s *SHA1Hash) Sum() (result [20]byte, err error) { - if 1 != C.X_EVP_DigestFinal_ex(s.ctx, - (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + if C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 { return result, errors.New("openssl: sha1: cannot finalize ctx") } return result, s.Reset() diff --git a/vendor/github.com/libp2p/go-openssl/sha256.go b/vendor/github.com/libp2p/go-openssl/sha256.go index d25c7a959..d9189a94b 100644 --- a/vendor/github.com/libp2p/go-openssl/sha256.go +++ b/vendor/github.com/libp2p/go-openssl/sha256.go @@ -51,7 +51,7 @@ func (s *SHA256Hash) Close() { } func (s *SHA256Hash) Reset() error { - if 1 != C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha256(), engineRef(s.engine)) { + if C.X_EVP_DigestInit_ex(s.ctx, C.X_EVP_sha256(), engineRef(s.engine)) != 1 { return errors.New("openssl: sha256: cannot init digest ctx") } return nil @@ -61,16 +61,16 @@ func (s *SHA256Hash) Write(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil } - if 1 != C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), - C.size_t(len(p))) { + if C.X_EVP_DigestUpdate(s.ctx, unsafe.Pointer(&p[0]), + C.size_t(len(p))) != 1 { return 0, errors.New("openssl: sha256: cannot update digest") } return len(p), nil } func (s *SHA256Hash) Sum() (result [32]byte, err error) { - if 1 != C.X_EVP_DigestFinal_ex(s.ctx, - (*C.uchar)(unsafe.Pointer(&result[0])), nil) { + if C.X_EVP_DigestFinal_ex(s.ctx, + (*C.uchar)(unsafe.Pointer(&result[0])), nil) != 1 { return result, errors.New("openssl: sha256: cannot finalize ctx") } return result, s.Reset() diff --git a/vendor/github.com/libp2p/go-openssl/shim.c b/vendor/github.com/libp2p/go-openssl/shim.c index 6e680841c..b27a57432 100644 --- a/vendor/github.com/libp2p/go-openssl/shim.c +++ b/vendor/github.com/libp2p/go-openssl/shim.c @@ -428,7 +428,7 @@ int X_SSL_session_reused(SSL *ssl) { } int X_SSL_new_index() { - return SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); + return SSL_get_ex_new_index(0, NULL, NULL, NULL, go_ssl_crypto_ex_free); } int X_SSL_verify_cb(int ok, X509_STORE_CTX* store) { @@ -475,6 +475,14 @@ int X_SSL_CTX_new_index() { return SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); } +int X_SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version) { + return SSL_CTX_set_min_proto_version(ctx, version); +} + +int X_SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version) { + return SSL_CTX_set_max_proto_version(ctx, version); +} + long X_SSL_CTX_set_options(SSL_CTX* ctx, long options) { return SSL_CTX_set_options(ctx, options); } diff --git a/vendor/github.com/libp2p/go-openssl/shim.h b/vendor/github.com/libp2p/go-openssl/shim.h index c63a95953..94fe8c612 100644 --- a/vendor/github.com/libp2p/go-openssl/shim.h +++ b/vendor/github.com/libp2p/go-openssl/shim.h @@ -67,6 +67,8 @@ extern int X_SSL_verify_cb(int ok, X509_STORE_CTX* store); /* SSL_CTX methods */ extern int X_SSL_CTX_new_index(); +extern int X_SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version); +extern int X_SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version); extern long X_SSL_CTX_set_options(SSL_CTX* ctx, long options); extern long X_SSL_CTX_clear_options(SSL_CTX* ctx, long options); extern long X_SSL_CTX_get_options(SSL_CTX* ctx); diff --git a/vendor/github.com/libp2p/go-openssl/ssl.go b/vendor/github.com/libp2p/go-openssl/ssl.go index 117c30c0f..b187d15d5 100644 --- a/vendor/github.com/libp2p/go-openssl/ssl.go +++ b/vendor/github.com/libp2p/go-openssl/ssl.go @@ -20,6 +20,8 @@ import "C" import ( "os" "unsafe" + + "github.com/mattn/go-pointer" ) type SSLTLSExtErr int @@ -53,7 +55,7 @@ func go_ssl_verify_cb_thunk(p unsafe.Pointer, ok C.int, ctx *C.X509_STORE_CTX) C os.Exit(1) } }() - verify_cb := (*SSL)(p).verify_cb + verify_cb := pointer.Restore(p).(*SSL).verify_cb // set up defaults just in case verify_cb is nil if verify_cb != nil { store := &CertificateStoreCtx{ctx: ctx} @@ -159,11 +161,11 @@ func sni_cb_thunk(p unsafe.Pointer, con *C.SSL, ad unsafe.Pointer, arg unsafe.Po } }() - sni_cb := (*Ctx)(p).sni_cb + sni_cb := pointer.Restore(p).(*Ctx).sni_cb s := &SSL{ssl: con} // This attaches a pointer to our SSL struct into the SNI callback. - C.SSL_set_ex_data(s.ssl, get_ssl_idx(), unsafe.Pointer(s)) + C.SSL_set_ex_data(s.ssl, get_ssl_idx(), pointer.Save(s)) // Note: this is ctx.sni_cb, not C.sni_cb return C.int(sni_cb(s)) diff --git a/vendor/github.com/libp2p/go-openssl/tickets.go b/vendor/github.com/libp2p/go-openssl/tickets.go index a064d3859..2ee8ed9b8 100644 --- a/vendor/github.com/libp2p/go-openssl/tickets.go +++ b/vendor/github.com/libp2p/go-openssl/tickets.go @@ -20,6 +20,8 @@ import "C" import ( "os" "unsafe" + + "github.com/mattn/go-pointer" ) const ( @@ -127,7 +129,7 @@ func go_ticket_key_cb_thunk(p unsafe.Pointer, s *C.SSL, key_name *C.uchar, } }() - ctx := (*Ctx)(p) + ctx := pointer.Restore(p).(*Ctx) store := ctx.ticket_store if store == nil { // TODO(jeff): should this be an error condition? it doesn't make sense diff --git a/vendor/github.com/libp2p/go-openssl/utils/future.go b/vendor/github.com/libp2p/go-openssl/utils/future.go index fa1bbbfb8..df2d8312c 100644 --- a/vendor/github.com/libp2p/go-openssl/utils/future.go +++ b/vendor/github.com/libp2p/go-openssl/utils/future.go @@ -45,35 +45,35 @@ func NewFuture() *Future { } // Get blocks until the Future has a value set. -func (self *Future) Get() (interface{}, error) { - self.mutex.Lock() - defer self.mutex.Unlock() +func (f *Future) Get() (interface{}, error) { + f.mutex.Lock() + defer f.mutex.Unlock() for { - if self.received { - return self.val, self.err + if f.received { + return f.val, f.err } - self.cond.Wait() + f.cond.Wait() } } // Fired returns whether or not a value has been set. If Fired is true, Get // won't block. -func (self *Future) Fired() bool { - self.mutex.Lock() - defer self.mutex.Unlock() - return self.received +func (f *Future) Fired() bool { + f.mutex.Lock() + defer f.mutex.Unlock() + return f.received } // Set provides the value to present and future Get calls. If Set has already // been called, this is a no-op. -func (self *Future) Set(val interface{}, err error) { - self.mutex.Lock() - defer self.mutex.Unlock() - if self.received { +func (f *Future) Set(val interface{}, err error) { + f.mutex.Lock() + defer f.mutex.Unlock() + if f.received { return } - self.received = true - self.val = val - self.err = err - self.cond.Broadcast() + f.received = true + f.val = val + f.err = err + f.cond.Broadcast() } diff --git a/vendor/github.com/libp2p/go-openssl/version.json b/vendor/github.com/libp2p/go-openssl/version.json new file mode 100644 index 000000000..557859c53 --- /dev/null +++ b/vendor/github.com/libp2p/go-openssl/version.json @@ -0,0 +1,3 @@ +{ + "version": "v0.1.0" +} diff --git a/vendor/github.com/libp2p/go-yamux/v3/version.json b/vendor/github.com/libp2p/go-yamux/v3/version.json deleted file mode 100644 index 86d7f5ec6..000000000 --- a/vendor/github.com/libp2p/go-yamux/v3/version.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "version": "v3.1.2" -} diff --git a/vendor/github.com/libp2p/go-yamux/v3/.gitignore b/vendor/github.com/libp2p/go-yamux/v4/.gitignore similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/.gitignore rename to vendor/github.com/libp2p/go-yamux/v4/.gitignore diff --git a/vendor/github.com/libp2p/go-yamux/v3/LICENSE b/vendor/github.com/libp2p/go-yamux/v4/LICENSE similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/LICENSE rename to vendor/github.com/libp2p/go-yamux/v4/LICENSE diff --git a/vendor/github.com/libp2p/go-yamux/v3/LICENSE-BSD b/vendor/github.com/libp2p/go-yamux/v4/LICENSE-BSD similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/LICENSE-BSD rename to vendor/github.com/libp2p/go-yamux/v4/LICENSE-BSD diff --git a/vendor/github.com/libp2p/go-yamux/v3/README.md b/vendor/github.com/libp2p/go-yamux/v4/README.md similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/README.md rename to vendor/github.com/libp2p/go-yamux/v4/README.md diff --git a/vendor/github.com/libp2p/go-yamux/v3/addr.go b/vendor/github.com/libp2p/go-yamux/v4/addr.go similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/addr.go rename to vendor/github.com/libp2p/go-yamux/v4/addr.go diff --git a/vendor/github.com/libp2p/go-yamux/v3/const.go b/vendor/github.com/libp2p/go-yamux/v4/const.go similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/const.go rename to vendor/github.com/libp2p/go-yamux/v4/const.go diff --git a/vendor/github.com/libp2p/go-yamux/v3/deadline.go b/vendor/github.com/libp2p/go-yamux/v4/deadline.go similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/deadline.go rename to vendor/github.com/libp2p/go-yamux/v4/deadline.go diff --git a/vendor/github.com/libp2p/go-yamux/v3/mux.go b/vendor/github.com/libp2p/go-yamux/v4/mux.go similarity index 89% rename from vendor/github.com/libp2p/go-yamux/v3/mux.go rename to vendor/github.com/libp2p/go-yamux/v4/mux.go index 458a0e210..edd2e388b 100644 --- a/vendor/github.com/libp2p/go-yamux/v3/mux.go +++ b/vendor/github.com/libp2p/go-yamux/v4/mux.go @@ -25,6 +25,9 @@ type Config struct { // KeepAliveInterval is how often to perform the keep alive KeepAliveInterval time.Duration + // MeasureRTTInterval is how often to re-measure the round trip time + MeasureRTTInterval time.Duration + // ConnectionWriteTimeout is meant to be a "safety valve" timeout after // we which will suspect a problem with the underlying connection and // close it. This is only applied to writes, where's there's generally @@ -69,6 +72,7 @@ func DefaultConfig() *Config { PingBacklog: 32, EnableKeepAlive: true, KeepAliveInterval: 30 * time.Second, + MeasureRTTInterval: 30 * time.Second, ConnectionWriteTimeout: 10 * time.Second, MaxIncomingStreams: 1000, InitialStreamWindowSize: initialStreamWindow, @@ -88,6 +92,10 @@ func VerifyConfig(config *Config) error { if config.KeepAliveInterval == 0 { return fmt.Errorf("keep-alive interval must be positive") } + if config.MeasureRTTInterval == 0 { + return fmt.Errorf("measure-rtt interval must be positive") + } + if config.InitialStreamWindowSize < initialStreamWindow { return errors.New("InitialStreamWindowSize must be larger or equal 256 kB") } @@ -109,7 +117,7 @@ func VerifyConfig(config *Config) error { // Server is used to initialize a new server-side connection. // There must be at most one server-side connection. If a nil config is // provided, the DefaultConfiguration will be used. -func Server(conn net.Conn, config *Config, mm MemoryManager) (*Session, error) { +func Server(conn net.Conn, config *Config, mm func() (MemoryManager, error)) (*Session, error) { if config == nil { config = DefaultConfig() } @@ -121,7 +129,7 @@ func Server(conn net.Conn, config *Config, mm MemoryManager) (*Session, error) { // Client is used to initialize a new client-side connection. // There must be at most one client-side connection. -func Client(conn net.Conn, config *Config, mm MemoryManager) (*Session, error) { +func Client(conn net.Conn, config *Config, mm func() (MemoryManager, error)) (*Session, error) { if config == nil { config = DefaultConfig() } diff --git a/vendor/github.com/libp2p/go-yamux/v3/ping.go b/vendor/github.com/libp2p/go-yamux/v4/ping.go similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/ping.go rename to vendor/github.com/libp2p/go-yamux/v4/ping.go diff --git a/vendor/github.com/libp2p/go-yamux/v3/session.go b/vendor/github.com/libp2p/go-yamux/v4/session.go similarity index 90% rename from vendor/github.com/libp2p/go-yamux/v3/session.go rename to vendor/github.com/libp2p/go-yamux/v4/session.go index 38adcd6e9..aecc20b60 100644 --- a/vendor/github.com/libp2p/go-yamux/v3/session.go +++ b/vendor/github.com/libp2p/go-yamux/v4/session.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "log" "math" "net" @@ -23,19 +22,24 @@ import ( // Memory is allocated: // 1. When opening / accepting a new stream. This uses the highest priority. // 2. When trying to increase the stream receive window. This uses a lower priority. +// This is a subset of the libp2p's resource manager ResourceScopeSpan interface. type MemoryManager interface { - // ReserveMemory reserves memory / buffer. ReserveMemory(size int, prio uint8) error + // ReleaseMemory explicitly releases memory previously reserved with ReserveMemory ReleaseMemory(size int) + + // Done ends the span and releases associated resources. + Done() } type nullMemoryManagerImpl struct{} func (n nullMemoryManagerImpl) ReserveMemory(size int, prio uint8) error { return nil } func (n nullMemoryManagerImpl) ReleaseMemory(size int) {} +func (n nullMemoryManagerImpl) Done() {} -var nullMemoryManager MemoryManager = &nullMemoryManagerImpl{} +var nullMemoryManager = &nullMemoryManagerImpl{} // Session is used to wrap a reliable ordered connection and to // multiplex it into multiple streams. @@ -66,7 +70,7 @@ type Session struct { // reader is a buffered reader reader io.Reader - memoryManager MemoryManager + newMemoryManager func() (MemoryManager, error) // pings is used to track inflight pings pingLock sync.Mutex @@ -121,31 +125,31 @@ type Session struct { } // newSession is used to construct a new session -func newSession(config *Config, conn net.Conn, client bool, readBuf int, memoryManager MemoryManager) *Session { +func newSession(config *Config, conn net.Conn, client bool, readBuf int, newMemoryManager func() (MemoryManager, error)) *Session { var reader io.Reader = conn if readBuf > 0 { reader = bufio.NewReaderSize(reader, readBuf) } - if memoryManager == nil { - memoryManager = nullMemoryManager + if newMemoryManager == nil { + newMemoryManager = func() (MemoryManager, error) { return nullMemoryManager, nil } } s := &Session{ - config: config, - client: client, - logger: log.New(config.LogOutput, "", log.LstdFlags), - conn: conn, - reader: reader, - streams: make(map[uint32]*Stream), - inflight: make(map[uint32]struct{}), - synCh: make(chan struct{}, config.AcceptBacklog), - acceptCh: make(chan *Stream, config.AcceptBacklog), - sendCh: make(chan []byte, 64), - pongCh: make(chan uint32, config.PingBacklog), - pingCh: make(chan uint32), - recvDoneCh: make(chan struct{}), - sendDoneCh: make(chan struct{}), - shutdownCh: make(chan struct{}), - memoryManager: memoryManager, + config: config, + client: client, + logger: log.New(config.LogOutput, "", log.LstdFlags), + conn: conn, + reader: reader, + streams: make(map[uint32]*Stream), + inflight: make(map[uint32]struct{}), + synCh: make(chan struct{}, config.AcceptBacklog), + acceptCh: make(chan *Stream, config.AcceptBacklog), + sendCh: make(chan []byte, 64), + pongCh: make(chan uint32, config.PingBacklog), + pingCh: make(chan uint32), + recvDoneCh: make(chan struct{}), + sendDoneCh: make(chan struct{}), + shutdownCh: make(chan struct{}), + newMemoryManager: newMemoryManager, } if client { s.nextStreamID = 1 @@ -157,7 +161,7 @@ func newSession(config *Config, conn net.Conn, client bool, readBuf int, memoryM } go s.recv() go s.send() - go s.measureRTT() + go s.startMeasureRTT() return s } @@ -212,7 +216,11 @@ func (s *Session) OpenStream(ctx context.Context) (*Stream, error) { return nil, s.shutdownErr } - if err := s.memoryManager.ReserveMemory(initialStreamWindow, 255); err != nil { + span, err := s.newMemoryManager() + if err != nil { + return nil, fmt.Errorf("failed to create resource scope span: %w", err) + } + if err := span.ReserveMemory(initialStreamWindow, 255); err != nil { return nil, err } @@ -220,6 +228,7 @@ GET_ID: // Get an ID, and check for stream exhaustion id := atomic.LoadUint32(&s.nextStreamID) if id >= math.MaxUint32-1 { + span.Done() return nil, ErrStreamsExhausted } if !atomic.CompareAndSwapUint32(&s.nextStreamID, id, id+2) { @@ -227,7 +236,7 @@ GET_ID: } // Register the stream - stream := newStream(s, id, streamInit, initialStreamWindow) + stream := newStream(s, id, streamInit, initialStreamWindow, span) s.streamLock.Lock() s.streams[id] = stream s.inflight[id] = struct{}{} @@ -235,6 +244,7 @@ GET_ID: // Send the window update to create if err := stream.sendWindowUpdate(); err != nil { + defer span.Done() select { case <-s.synCh: default: @@ -294,14 +304,10 @@ func (s *Session) Close() error { s.streamLock.Lock() defer s.streamLock.Unlock() - var memory int for id, stream := range s.streams { - memory += stream.memory stream.forceClose() delete(s.streams, id) - } - if memory > 0 { - s.memoryManager.ReleaseMemory(memory) + stream.memorySpan.Done() } return nil } @@ -335,7 +341,25 @@ func (s *Session) measureRTT() { if err != nil { return } - atomic.StoreInt64(&s.rtt, rtt.Nanoseconds()) + if !atomic.CompareAndSwapInt64(&s.rtt, 0, rtt.Nanoseconds()) { + prev := atomic.LoadInt64(&s.rtt) + smoothedRTT := prev/2 + rtt.Nanoseconds()/2 + atomic.StoreInt64(&s.rtt, smoothedRTT) + } +} + +func (s *Session) startMeasureRTT() { + s.measureRTT() + t := time.NewTicker(s.config.MeasureRTTInterval) + defer t.Stop() + for { + select { + case <-s.CloseChan(): + return + case <-t.C: + s.measureRTT() + } + } } // 0 if we don't yet have a measurement @@ -692,7 +716,7 @@ func (s *Session) handleStreamMessage(hdr header) error { // Drain any data on the wire if hdr.MsgType() == typeData && hdr.Length() > 0 { s.logger.Printf("[WARN] yamux: Discarding data for stream: %d", id) - if _, err := io.CopyN(ioutil.Discard, s.reader, int64(hdr.Length())); err != nil { + if _, err := io.CopyN(io.Discard, s.reader, int64(hdr.Length())); err != nil { s.logger.Printf("[ERR] yamux: Failed to discard data: %v", err) return nil } @@ -782,10 +806,14 @@ func (s *Session) incomingStream(id uint32) error { } // Allocate a new stream - if err := s.memoryManager.ReserveMemory(initialStreamWindow, 255); err != nil { + span, err := s.newMemoryManager() + if err != nil { + return fmt.Errorf("failed to create resource span: %w", err) + } + if err := span.ReserveMemory(initialStreamWindow, 255); err != nil { return err } - stream := newStream(s, id, streamSYNReceived, initialStreamWindow) + stream := newStream(s, id, streamSYNReceived, initialStreamWindow, span) s.streamLock.Lock() defer s.streamLock.Unlock() @@ -796,14 +824,14 @@ func (s *Session) incomingStream(id uint32) error { if sendErr := s.sendMsg(s.goAway(goAwayProtoErr), nil, nil); sendErr != nil { s.logger.Printf("[WARN] yamux: failed to send go away: %v", sendErr) } - s.memoryManager.ReleaseMemory(stream.memory) + span.Done() return ErrDuplicateStream } if s.numIncomingStreams >= s.config.MaxIncomingStreams { // too many active streams at the same time s.logger.Printf("[WARN] yamux: MaxIncomingStreams exceeded, forcing stream reset") - s.memoryManager.ReleaseMemory(stream.memory) + defer span.Done() hdr := encode(typeWindowUpdate, flagRST, id, 0) return s.sendMsg(hdr, nil, nil) } @@ -818,6 +846,7 @@ func (s *Session) incomingStream(id uint32) error { return nil default: // Backlog exceeded! RST the stream + defer span.Done() s.logger.Printf("[WARN] yamux: backlog exceeded, forcing stream reset") s.deleteStream(id) hdr := encode(typeWindowUpdate, flagRST, id, 0) @@ -856,8 +885,8 @@ func (s *Session) deleteStream(id uint32) { s.numIncomingStreams-- } } - s.memoryManager.ReleaseMemory(str.memory) delete(s.streams, id) + str.memorySpan.Done() } // establishStream is used to mark a stream that was in the diff --git a/vendor/github.com/libp2p/go-yamux/v3/spec.md b/vendor/github.com/libp2p/go-yamux/v4/spec.md similarity index 100% rename from vendor/github.com/libp2p/go-yamux/v3/spec.md rename to vendor/github.com/libp2p/go-yamux/v4/spec.md diff --git a/vendor/github.com/libp2p/go-yamux/v3/stream.go b/vendor/github.com/libp2p/go-yamux/v4/stream.go similarity index 96% rename from vendor/github.com/libp2p/go-yamux/v3/stream.go rename to vendor/github.com/libp2p/go-yamux/v4/stream.go index 9175268c3..88d551e65 100644 --- a/vendor/github.com/libp2p/go-yamux/v3/stream.go +++ b/vendor/github.com/libp2p/go-yamux/v4/stream.go @@ -31,7 +31,7 @@ const ( type Stream struct { sendWindow uint32 - memory int + memorySpan MemoryManager id uint32 session *Session @@ -53,15 +53,15 @@ type Stream struct { // newStream is used to construct a new stream within a given session for an ID. // It assumes that a memory allocation has been obtained for the initialWindow. -func newStream(session *Session, id uint32, state streamState, initialWindow uint32) *Stream { +func newStream(session *Session, id uint32, state streamState, initialWindow uint32, memorySpan MemoryManager) *Stream { s := &Stream{ id: id, session: session, state: state, sendWindow: initialStreamWindow, - memory: int(initialWindow), readDeadline: makePipeDeadline(), writeDeadline: makePipeDeadline(), + memorySpan: memorySpan, // Initialize the recvBuf with initialStreamWindow, not config.InitialStreamWindowSize. // The peer isn't allowed to send more data than initialStreamWindow until we've sent // the first window update (which will grant it up to config.InitialStreamWindowSize). @@ -229,9 +229,8 @@ func (s *Stream) sendWindowUpdate() error { } if recvWindow > s.recvWindow { grow := recvWindow - s.recvWindow - if err := s.session.memoryManager.ReserveMemory(int(grow), 128); err == nil { + if err := s.memorySpan.ReserveMemory(int(grow), 128); err == nil { s.recvWindow = recvWindow - s.memory += int(grow) _, delta = s.recvBuf.GrowTo(s.recvWindow, true) } } @@ -385,22 +384,24 @@ func (s *Stream) cleanup() { // based on set flags, if any. Lock must be held func (s *Stream) processFlags(flags uint16) { // Close the stream without holding the state lock - closeStream := false + var closeStream bool defer func() { if closeStream { s.cleanup() } }() - s.stateLock.Lock() - defer s.stateLock.Unlock() if flags&flagACK == flagACK { + s.stateLock.Lock() if s.state == streamSYNSent { s.state = streamEstablished } + s.stateLock.Unlock() s.session.establishStream(s.id) } if flags&flagFIN == flagFIN { + var notify bool + s.stateLock.Lock() if s.readState == halfOpen { s.readState = halfClosed if s.writeState != halfOpen { @@ -408,10 +409,15 @@ func (s *Stream) processFlags(flags uint16) { closeStream = true s.state = streamFinished } + notify = true + } + s.stateLock.Unlock() + if notify { s.notifyWaiting() } } if flags&flagRST == flagRST { + s.stateLock.Lock() if s.readState == halfOpen { s.readState = halfReset } @@ -419,6 +425,7 @@ func (s *Stream) processFlags(flags uint16) { s.writeState = halfReset } s.state = streamFinished + s.stateLock.Unlock() closeStream = true s.notifyWaiting() } diff --git a/vendor/github.com/libp2p/go-yamux/v3/util.go b/vendor/github.com/libp2p/go-yamux/v4/util.go similarity index 87% rename from vendor/github.com/libp2p/go-yamux/v3/util.go rename to vendor/github.com/libp2p/go-yamux/v4/util.go index aeccd24b8..62bf0d1c9 100644 --- a/vendor/github.com/libp2p/go-yamux/v3/util.go +++ b/vendor/github.com/libp2p/go-yamux/v4/util.go @@ -40,30 +40,28 @@ func min(values ...uint32) uint32 { // The segmented buffer looks like: // -// | data | empty space | -// < window (10) > -// < len (5) > < cap (5) > +// | data | empty space | +// < window (10) > +// < len (5) > < cap (5) > // // As data is read, the buffer gets updated like so: // -// | data | empty space | -// < window (8) > -// < len (3) > < cap (5) > +// | data | empty space | +// < window (8) > +// < len (3) > < cap (5) > // // It can then grow as follows (given a "max" of 10): // -// -// | data | empty space | -// < window (10) > -// < len (3) > < cap (7) > +// | data | empty space | +// < window (10) > +// < len (3) > < cap (7) > // // Data can then be written into the empty space, expanding len, // and shrinking cap: // -// | data | empty space | -// < window (10) > -// < len (5) > < cap (5) > -// +// | data | empty space | +// < window (10) > +// < len (5) > < cap (5) > type segmentedBuffer struct { cap uint32 len uint32 diff --git a/vendor/github.com/libp2p/go-yamux/v4/version.json b/vendor/github.com/libp2p/go-yamux/v4/version.json new file mode 100644 index 000000000..2354b515d --- /dev/null +++ b/vendor/github.com/libp2p/go-yamux/v4/version.json @@ -0,0 +1,3 @@ +{ + "version": "v4.0.0" +} diff --git a/vendor/github.com/lucas-clemente/quic-go/README.md b/vendor/github.com/lucas-clemente/quic-go/README.md index f284174c2..f33ede45d 100644 --- a/vendor/github.com/lucas-clemente/quic-go/README.md +++ b/vendor/github.com/lucas-clemente/quic-go/README.md @@ -5,13 +5,13 @@ [![PkgGoDev](https://pkg.go.dev/badge/github.com/lucas-clemente/quic-go)](https://pkg.go.dev/github.com/lucas-clemente/quic-go) [![Code Coverage](https://img.shields.io/codecov/c/github/lucas-clemente/quic-go/master.svg?style=flat-square)](https://codecov.io/gh/lucas-clemente/quic-go/) -quic-go is an implementation of the [QUIC protocol, RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000) protocol in Go, including the [Unreliable Datagram Extension, RFC 9221](https://datatracker.ietf.org/doc/html/rfc9221). +quic-go is an implementation of the QUIC protocol ([RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000), [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001), [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)) in Go, including the Unreliable Datagram Extension ([RFC 9221](https://datatracker.ietf.org/doc/html/rfc9221)). It has support for HTTP/3 ([RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114)), including QPACK ([RFC 9204](https://datatracker.ietf.org/doc/html/rfc9204)). -In addition to RFC 9000, it currently implements the [IETF QUIC draft-29](https://tools.ietf.org/html/draft-ietf-quic-transport-29). Support for draft-29 will eventually be dropped, as it is phased out of the ecosystem. +In addition to the RFCs listed above, it currently implements the [IETF QUIC draft-29](https://tools.ietf.org/html/draft-ietf-quic-transport-29). Support for draft-29 will eventually be dropped, as it is phased out of the ecosystem. ## Guides -*We currently support Go 1.16.x, Go 1.17.x, and Go 1.18.x.* +*We currently support Go 1.18.x and Go 1.19.x.* Running tests: @@ -54,7 +54,7 @@ http.Client{ | [v2ray-core](https://github.com/v2fly/v2ray-core) | A platform for building proxies to bypass network restrictions | ![GitHub Repo stars](https://img.shields.io/github/stars/v2fly/v2ray-core?style=flat-square) | | [cloudflared](https://github.com/cloudflare/cloudflared) | A tunneling daemon that proxies traffic from the Cloudflare network to your origins | ![GitHub Repo stars](https://img.shields.io/github/stars/cloudflare/cloudflared?style=flat-square) | | [OONI Probe](https://github.com/ooni/probe-cli) | The Open Observatory of Network Interference (OONI) aims to empower decentralized efforts in documenting Internet censorship around the world. | ![GitHub Repo stars](https://img.shields.io/github/stars/ooni/probe-cli?style=flat-square) | - +| [YoMo](https://github.com/yomorun/yomo) | Streaming Serverless Framework for Geo-distributed System | ![GitHub Repo stars](https://img.shields.io/github/stars/yomorun/yomo?style=flat-square) | ## Contributing diff --git a/vendor/github.com/lucas-clemente/quic-go/client.go b/vendor/github.com/lucas-clemente/quic-go/client.go index be8390e65..3d7f15059 100644 --- a/vendor/github.com/lucas-clemente/quic-go/client.go +++ b/vendor/github.com/lucas-clemente/quic-go/client.go @@ -42,11 +42,8 @@ type client struct { logger utils.Logger } -var ( - // make it possible to mock connection ID generation in the tests - generateConnectionID = protocol.GenerateConnectionID - generateConnectionIDForInitial = protocol.GenerateConnectionIDForInitial -) +// make it possible to mock connection ID for initial generation in the tests +var generateConnectionIDForInitial = protocol.GenerateConnectionIDForInitial // DialAddr establishes a new QUIC connection to a server. // It uses a new UDP connection and closes this connection when the QUIC connection is closed. @@ -193,7 +190,7 @@ func dialContext( return nil, err } config = populateClientConfig(config, createdPacketConn) - packetHandlers, err := getMultiplexer().AddConn(pconn, config.ConnectionIDLength, config.StatelessResetKey, config.Tracer) + packetHandlers, err := getMultiplexer().AddConn(pconn, config.ConnectionIDGenerator.ConnectionIDLen(), config.StatelessResetKey, config.Tracer) if err != nil { return nil, err } @@ -256,7 +253,7 @@ func newClient( } } - srcConnID, err := generateConnectionID(config.ConnectionIDLength) + srcConnID, err := config.ConnectionIDGenerator.GenerateConnectionID() if err != nil { return nil, err } diff --git a/vendor/github.com/lucas-clemente/quic-go/closed_conn.go b/vendor/github.com/lucas-clemente/quic-go/closed_conn.go index 35c2d7390..d46e393a6 100644 --- a/vendor/github.com/lucas-clemente/quic-go/closed_conn.go +++ b/vendor/github.com/lucas-clemente/quic-go/closed_conn.go @@ -1,7 +1,8 @@ package quic import ( - "sync" + "math/bits" + "net" "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/utils" @@ -11,87 +12,38 @@ import ( // When receiving packets for such a connection, we need to retransmit the packet containing the CONNECTION_CLOSE frame, // with an exponential backoff. type closedLocalConn struct { - conn sendConn - connClosePacket []byte - - closeOnce sync.Once - closeChan chan struct{} // is closed when the connection is closed or destroyed - - receivedPackets chan *receivedPacket - counter uint64 // number of packets received - + counter uint32 perspective protocol.Perspective + logger utils.Logger - logger utils.Logger + sendPacket func(net.Addr, *packetInfo) } var _ packetHandler = &closedLocalConn{} // newClosedLocalConn creates a new closedLocalConn and runs it. -func newClosedLocalConn( - conn sendConn, - connClosePacket []byte, - perspective protocol.Perspective, - logger utils.Logger, -) packetHandler { - s := &closedLocalConn{ - conn: conn, - connClosePacket: connClosePacket, - perspective: perspective, - logger: logger, - closeChan: make(chan struct{}), - receivedPackets: make(chan *receivedPacket, 64), - } - go s.run() - return s -} - -func (s *closedLocalConn) run() { - for { - select { - case p := <-s.receivedPackets: - s.handlePacketImpl(p) - case <-s.closeChan: - return - } +func newClosedLocalConn(sendPacket func(net.Addr, *packetInfo), pers protocol.Perspective, logger utils.Logger) packetHandler { + return &closedLocalConn{ + sendPacket: sendPacket, + perspective: pers, + logger: logger, } } -func (s *closedLocalConn) handlePacket(p *receivedPacket) { - select { - case s.receivedPackets <- p: - default: - } -} - -func (s *closedLocalConn) handlePacketImpl(_ *receivedPacket) { - s.counter++ +func (c *closedLocalConn) handlePacket(p *receivedPacket) { + c.counter++ // exponential backoff // only send a CONNECTION_CLOSE for the 1st, 2nd, 4th, 8th, 16th, ... packet arriving - for n := s.counter; n > 1; n = n / 2 { - if n%2 != 0 { - return - } - } - s.logger.Debugf("Received %d packets after sending CONNECTION_CLOSE. Retransmitting.", s.counter) - if err := s.conn.Write(s.connClosePacket); err != nil { - s.logger.Debugf("Error retransmitting CONNECTION_CLOSE: %s", err) + if bits.OnesCount32(c.counter) != 1 { + return } + c.logger.Debugf("Received %d packets after sending CONNECTION_CLOSE. Retransmitting.", c.counter) + c.sendPacket(p.remoteAddr, p.info) } -func (s *closedLocalConn) shutdown() { - s.destroy(nil) -} - -func (s *closedLocalConn) destroy(error) { - s.closeOnce.Do(func() { - close(s.closeChan) - }) -} - -func (s *closedLocalConn) getPerspective() protocol.Perspective { - return s.perspective -} +func (c *closedLocalConn) shutdown() {} +func (c *closedLocalConn) destroy(error) {} +func (c *closedLocalConn) getPerspective() protocol.Perspective { return c.perspective } // A closedRemoteConn is a connection that was closed remotely. // For such a connection, we might receive reordered packets that were sent before the CONNECTION_CLOSE. diff --git a/vendor/github.com/lucas-clemente/quic-go/codecov.yml b/vendor/github.com/lucas-clemente/quic-go/codecov.yml index ee9cfd3b3..074d98325 100644 --- a/vendor/github.com/lucas-clemente/quic-go/codecov.yml +++ b/vendor/github.com/lucas-clemente/quic-go/codecov.yml @@ -12,6 +12,7 @@ coverage: - internal/utils/newconnectionid_linkedlist.go - internal/utils/packetinterval_linkedlist.go - internal/utils/linkedlist/linkedlist.go + - logging/null_tracer.go - fuzzing/ - metrics/ status: diff --git a/vendor/github.com/lucas-clemente/quic-go/config.go b/vendor/github.com/lucas-clemente/quic-go/config.go index 5d969a12a..0e8cc98a5 100644 --- a/vendor/github.com/lucas-clemente/quic-go/config.go +++ b/vendor/github.com/lucas-clemente/quic-go/config.go @@ -2,11 +2,11 @@ package quic import ( "errors" + "net" "time" - "github.com/lucas-clemente/quic-go/internal/utils" - "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/utils" ) // Clone clones a Config @@ -16,7 +16,7 @@ func (c *Config) Clone() *Config { } func (c *Config) handshakeTimeout() time.Duration { - return utils.MaxDuration(protocol.DefaultHandshakeTimeout, 2*c.HandshakeIdleTimeout) + return utils.Max(protocol.DefaultHandshakeTimeout, 2*c.HandshakeIdleTimeout) } func validateConfig(config *Config) error { @@ -35,12 +35,15 @@ func validateConfig(config *Config) error { // populateServerConfig populates fields in the quic.Config with their default values, if none are set // it may be called with nil func populateServerConfig(config *Config) *Config { - config = populateConfig(config) - if config.ConnectionIDLength == 0 { - config.ConnectionIDLength = protocol.DefaultConnectionIDLength + config = populateConfig(config, protocol.DefaultConnectionIDLength) + if config.MaxTokenAge == 0 { + config.MaxTokenAge = protocol.TokenValidity } - if config.AcceptToken == nil { - config.AcceptToken = defaultAcceptToken + if config.MaxRetryTokenAge == 0 { + config.MaxRetryTokenAge = protocol.RetryTokenValidity + } + if config.RequireAddressValidation == nil { + config.RequireAddressValidation = func(net.Addr) bool { return false } } return config } @@ -48,14 +51,16 @@ func populateServerConfig(config *Config) *Config { // populateClientConfig populates fields in the quic.Config with their default values, if none are set // it may be called with nil func populateClientConfig(config *Config, createdPacketConn bool) *Config { - config = populateConfig(config) - if config.ConnectionIDLength == 0 && !createdPacketConn { - config.ConnectionIDLength = protocol.DefaultConnectionIDLength + defaultConnIDLen := protocol.DefaultConnectionIDLength + if createdPacketConn { + defaultConnIDLen = 0 } + + config = populateConfig(config, defaultConnIDLen) return config } -func populateConfig(config *Config) *Config { +func populateConfig(config *Config, defaultConnIDLen int) *Config { if config == nil { config = &Config{} } @@ -63,6 +68,10 @@ func populateConfig(config *Config) *Config { if len(versions) == 0 { versions = protocol.SupportedVersions } + conIDLen := config.ConnectionIDLength + if config.ConnectionIDLength == 0 { + conIDLen = defaultConnIDLen + } handshakeIdleTimeout := protocol.DefaultHandshakeIdleTimeout if config.HandshakeIdleTimeout != 0 { handshakeIdleTimeout = config.HandshakeIdleTimeout @@ -99,12 +108,18 @@ func populateConfig(config *Config) *Config { } else if maxIncomingUniStreams < 0 { maxIncomingUniStreams = 0 } + connIDGenerator := config.ConnectionIDGenerator + if connIDGenerator == nil { + connIDGenerator = &protocol.DefaultConnectionIDGenerator{ConnLen: conIDLen} + } return &Config{ Versions: versions, HandshakeIdleTimeout: handshakeIdleTimeout, MaxIdleTimeout: idleTimeout, - AcceptToken: config.AcceptToken, + MaxTokenAge: config.MaxTokenAge, + MaxRetryTokenAge: config.MaxRetryTokenAge, + RequireAddressValidation: config.RequireAddressValidation, KeepAlivePeriod: config.KeepAlivePeriod, InitialStreamReceiveWindow: initialStreamReceiveWindow, MaxStreamReceiveWindow: maxStreamReceiveWindow, @@ -113,7 +128,8 @@ func populateConfig(config *Config) *Config { AllowConnectionWindowIncrease: config.AllowConnectionWindowIncrease, MaxIncomingStreams: maxIncomingStreams, MaxIncomingUniStreams: maxIncomingUniStreams, - ConnectionIDLength: config.ConnectionIDLength, + ConnectionIDLength: conIDLen, + ConnectionIDGenerator: connIDGenerator, StatelessResetKey: config.StatelessResetKey, TokenStore: config.TokenStore, EnableDatagrams: config.EnableDatagrams, diff --git a/vendor/github.com/lucas-clemente/quic-go/conn_id_generator.go b/vendor/github.com/lucas-clemente/quic-go/conn_id_generator.go index 90c2b7a6f..0421d678b 100644 --- a/vendor/github.com/lucas-clemente/quic-go/conn_id_generator.go +++ b/vendor/github.com/lucas-clemente/quic-go/conn_id_generator.go @@ -10,7 +10,7 @@ import ( ) type connIDGenerator struct { - connIDLen int + generator ConnectionIDGenerator highestSeq uint64 activeSrcConnIDs map[uint64]protocol.ConnectionID @@ -20,7 +20,7 @@ type connIDGenerator struct { getStatelessResetToken func(protocol.ConnectionID) protocol.StatelessResetToken removeConnectionID func(protocol.ConnectionID) retireConnectionID func(protocol.ConnectionID) - replaceWithClosed func(protocol.ConnectionID, packetHandler) + replaceWithClosed func([]protocol.ConnectionID, protocol.Perspective, []byte) queueControlFrame func(wire.Frame) version protocol.VersionNumber @@ -33,12 +33,13 @@ func newConnIDGenerator( getStatelessResetToken func(protocol.ConnectionID) protocol.StatelessResetToken, removeConnectionID func(protocol.ConnectionID), retireConnectionID func(protocol.ConnectionID), - replaceWithClosed func(protocol.ConnectionID, packetHandler), + replaceWithClosed func([]protocol.ConnectionID, protocol.Perspective, []byte), queueControlFrame func(wire.Frame), + generator ConnectionIDGenerator, version protocol.VersionNumber, ) *connIDGenerator { m := &connIDGenerator{ - connIDLen: initialConnectionID.Len(), + generator: generator, activeSrcConnIDs: make(map[uint64]protocol.ConnectionID), addConnectionID: addConnectionID, getStatelessResetToken: getStatelessResetToken, @@ -54,7 +55,7 @@ func newConnIDGenerator( } func (m *connIDGenerator) SetMaxActiveConnIDs(limit uint64) error { - if m.connIDLen == 0 { + if m.generator.ConnectionIDLen() == 0 { return nil } // The active_connection_id_limit transport parameter is the number of @@ -63,7 +64,7 @@ func (m *connIDGenerator) SetMaxActiveConnIDs(limit uint64) error { // transport parameter. // We currently don't send the preferred_address transport parameter, // so we can issue (limit - 1) connection IDs. - for i := uint64(len(m.activeSrcConnIDs)); i < utils.MinUint64(limit, protocol.MaxIssuedConnectionIDs); i++ { + for i := uint64(len(m.activeSrcConnIDs)); i < utils.Min(limit, protocol.MaxIssuedConnectionIDs); i++ { if err := m.issueNewConnID(); err != nil { return err } @@ -99,7 +100,7 @@ func (m *connIDGenerator) Retire(seq uint64, sentWithDestConnID protocol.Connect } func (m *connIDGenerator) issueNewConnID() error { - connID, err := protocol.GenerateConnectionID(m.connIDLen) + connID, err := m.generator.GenerateConnectionID() if err != nil { return err } @@ -130,11 +131,13 @@ func (m *connIDGenerator) RemoveAll() { } } -func (m *connIDGenerator) ReplaceWithClosed(handler packetHandler) { +func (m *connIDGenerator) ReplaceWithClosed(pers protocol.Perspective, connClose []byte) { + connIDs := make([]protocol.ConnectionID, 0, len(m.activeSrcConnIDs)+1) if m.initialClientDestConnID != nil { - m.replaceWithClosed(m.initialClientDestConnID, handler) + connIDs = append(connIDs, m.initialClientDestConnID) } for _, connID := range m.activeSrcConnIDs { - m.replaceWithClosed(connID, handler) + connIDs = append(connIDs, connID) } + m.replaceWithClosed(connIDs, pers, connClose) } diff --git a/vendor/github.com/lucas-clemente/quic-go/conn_id_manager.go b/vendor/github.com/lucas-clemente/quic-go/conn_id_manager.go index e1b025a98..c1bb42bef 100644 --- a/vendor/github.com/lucas-clemente/quic-go/conn_id_manager.go +++ b/vendor/github.com/lucas-clemente/quic-go/conn_id_manager.go @@ -6,11 +6,18 @@ import ( "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/qerr" "github.com/lucas-clemente/quic-go/internal/utils" + list "github.com/lucas-clemente/quic-go/internal/utils/linkedlist" "github.com/lucas-clemente/quic-go/internal/wire" ) +type newConnID struct { + SequenceNumber uint64 + ConnectionID protocol.ConnectionID + StatelessResetToken protocol.StatelessResetToken +} + type connIDManager struct { - queue utils.NewConnectionIDList + queue list.List[newConnID] handshakeComplete bool activeSequenceNumber uint64 @@ -71,7 +78,7 @@ func (h *connIDManager) add(f *wire.NewConnectionIDFrame) error { // Retire elements in the queue. // Doesn't retire the active connection ID. if f.RetirePriorTo > h.highestRetired { - var next *utils.NewConnectionIDElement + var next *list.Element[newConnID] for el := h.queue.Front(); el != nil; el = next { if el.Value.SequenceNumber >= f.RetirePriorTo { break @@ -104,7 +111,7 @@ func (h *connIDManager) add(f *wire.NewConnectionIDFrame) error { func (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID, resetToken protocol.StatelessResetToken) error { // insert a new element at the end if h.queue.Len() == 0 || h.queue.Back().Value.SequenceNumber < seq { - h.queue.PushBack(utils.NewConnectionID{ + h.queue.PushBack(newConnID{ SequenceNumber: seq, ConnectionID: connID, StatelessResetToken: resetToken, @@ -123,7 +130,7 @@ func (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID break } if el.Value.SequenceNumber > seq { - h.queue.InsertBefore(utils.NewConnectionID{ + h.queue.InsertBefore(newConnID{ SequenceNumber: seq, ConnectionID: connID, StatelessResetToken: resetToken, @@ -138,7 +145,7 @@ func (h *connIDManager) updateConnectionID() { h.queueControlFrame(&wire.RetireConnectionIDFrame{ SequenceNumber: h.activeSequenceNumber, }) - h.highestRetired = utils.MaxUint64(h.highestRetired, h.activeSequenceNumber) + h.highestRetired = utils.Max(h.highestRetired, h.activeSequenceNumber) if h.activeStatelessResetToken != nil { h.removeStatelessResetToken(*h.activeStatelessResetToken) } diff --git a/vendor/github.com/lucas-clemente/quic-go/connection.go b/vendor/github.com/lucas-clemente/quic-go/connection.go index ce45af86a..015d98adc 100644 --- a/vendor/github.com/lucas-clemente/quic-go/connection.go +++ b/vendor/github.com/lucas-clemente/quic-go/connection.go @@ -95,7 +95,7 @@ type connRunner interface { GetStatelessResetToken(protocol.ConnectionID) protocol.StatelessResetToken Retire(protocol.ConnectionID) Remove(protocol.ConnectionID) - ReplaceWithClosed(protocol.ConnectionID, packetHandler) + ReplaceWithClosed([]protocol.ConnectionID, protocol.Perspective, []byte) AddResetToken(protocol.StatelessResetToken, packetHandler) RemoveResetToken(protocol.StatelessResetToken) } @@ -242,6 +242,7 @@ var newConnection = func( tlsConf *tls.Config, tokenGenerator *handshake.TokenGenerator, enable0RTT bool, + clientAddressValidated bool, tracer logging.ConnectionTracer, tracingID uint64, logger utils.Logger, @@ -280,6 +281,7 @@ var newConnection = func( runner.Retire, runner.ReplaceWithClosed, s.queueControlFrame, + s.config.ConnectionIDGenerator, s.version, ) s.preSetup() @@ -288,6 +290,7 @@ var newConnection = func( 0, getMaxPacketSize(s.conn.RemoteAddr()), s.rttStats, + clientAddressValidated, s.perspective, s.tracer, s.logger, @@ -314,6 +317,8 @@ var newConnection = func( } if s.config.EnableDatagrams { params.MaxDatagramFrameSize = protocol.MaxDatagramFrameSize + } else { + params.MaxDatagramFrameSize = protocol.InvalidByteCount } if s.tracer != nil { s.tracer.SentTransportParameters(params) @@ -407,6 +412,7 @@ var newClientConnection = func( runner.Retire, runner.ReplaceWithClosed, s.queueControlFrame, + s.config.ConnectionIDGenerator, s.version, ) s.preSetup() @@ -415,6 +421,7 @@ var newClientConnection = func( initialPacketNumber, getMaxPacketSize(s.conn.RemoteAddr()), s.rttStats, + false, /* has no effect */ s.perspective, s.tracer, s.logger, @@ -438,6 +445,8 @@ var newClientConnection = func( } if s.config.EnableDatagrams { params.MaxDatagramFrameSize = protocol.MaxDatagramFrameSize + } else { + params.MaxDatagramFrameSize = protocol.InvalidByteCount } if s.tracer != nil { s.tracer.SentTransportParameters(params) @@ -532,9 +541,7 @@ func (s *connection) preSetup() { s.creationTime = now s.windowUpdateQueue = newWindowUpdateQueue(s.streamsMap, s.connFlowController, s.framer.QueueControlFrame) - if s.config.EnableDatagrams { - s.datagramQueue = newDatagramQueue(s.scheduleSending, s.logger) - } + s.datagramQueue = newDatagramQueue(s.scheduleSending, s.logger) } // run the connection main loop @@ -543,7 +550,11 @@ func (s *connection) run() error { s.timer = utils.NewTimer() - go s.cryptoStreamHandler.RunHandshake() + handshaking := make(chan struct{}) + go func() { + defer close(handshaking) + s.cryptoStreamHandler.RunHandshake() + }() go func() { if err := s.sendQueue.Run(); err != nil { s.destroyImpl(err) @@ -694,12 +705,13 @@ runLoop: } } + s.cryptoStreamHandler.Close() + <-handshaking s.handleCloseError(&closeErr) if e := (&errCloseForRecreating{}); !errors.As(closeErr.err, &e) && s.tracer != nil { s.tracer.Close() } s.logger.Infof("Connection %s closed.", s.logID) - s.cryptoStreamHandler.Close() s.sendQueue.Close() s.timer.Stop() return closeErr.err @@ -719,7 +731,7 @@ func (s *connection) Context() context.Context { } func (s *connection) supportsDatagrams() bool { - return s.peerParams.MaxDatagramFrameSize != protocol.InvalidByteCount + return s.peerParams.MaxDatagramFrameSize > 0 } func (s *connection) ConnectionState() ConnectionState { @@ -816,7 +828,7 @@ func (s *connection) handleHandshakeConfirmed() { if maxPacketSize == 0 { maxPacketSize = protocol.MaxByteCount } - maxPacketSize = utils.MinByteCount(maxPacketSize, protocol.MaxPacketBufferSize) + maxPacketSize = utils.Min(maxPacketSize, protocol.MaxPacketBufferSize) s.mtuDiscoverer = newMTUDiscoverer( s.rttStats, getMaxPacketSize(s.conn.RemoteAddr()), @@ -1513,7 +1525,7 @@ func (s *connection) handleCloseError(closeErr *closeError) { // If this is a remote close we're done here if closeErr.remote { - s.connIDGenerator.ReplaceWithClosed(newClosedRemoteConn(s.perspective)) + s.connIDGenerator.ReplaceWithClosed(s.perspective, nil) return } if closeErr.immediate { @@ -1530,8 +1542,7 @@ func (s *connection) handleCloseError(closeErr *closeError) { if err != nil { s.logger.Debugf("Error sending CONNECTION_CLOSE: %s", err) } - cs := newClosedLocalConn(s.conn, connClosePacket, s.perspective, s.logger) - s.connIDGenerator.ReplaceWithClosed(cs) + s.connIDGenerator.ReplaceWithClosed(s.perspective, connClosePacket) } func (s *connection) dropEncryptionLevel(encLevel protocol.EncryptionLevel) { @@ -1618,7 +1629,7 @@ func (s *connection) applyTransportParameters() { params := s.peerParams // Our local idle timeout will always be > 0. s.idleTimeout = utils.MinNonZeroDuration(s.config.MaxIdleTimeout, params.MaxIdleTimeout) - s.keepAliveInterval = utils.MinDuration(s.config.KeepAlivePeriod, utils.MinDuration(s.idleTimeout/2, protocol.MaxKeepAliveInterval)) + s.keepAliveInterval = utils.Min(s.config.KeepAlivePeriod, utils.Min(s.idleTimeout/2, protocol.MaxKeepAliveInterval)) s.streamsMap.UpdateLimits(params) s.packer.HandleTransportParameters(params) s.frameParser.SetAckDelayExponent(params.AckDelayExponent) @@ -1970,6 +1981,10 @@ func (s *connection) onStreamCompleted(id protocol.StreamID) { } func (s *connection) SendMessage(p []byte) error { + if !s.supportsDatagrams() { + return errors.New("datagram support disabled") + } + f := &wire.DatagramFrame{DataLenPresent: true} if protocol.ByteCount(len(p)) > f.MaxDataLen(s.peerParams.MaxDatagramFrameSize, s.version) { return errors.New("message too large") @@ -1980,6 +1995,9 @@ func (s *connection) SendMessage(p []byte) error { } func (s *connection) ReceiveMessage() ([]byte, error) { + if !s.config.EnableDatagrams { + return nil, errors.New("datagram support disabled") + } return s.datagramQueue.Receive() } diff --git a/vendor/github.com/lucas-clemente/quic-go/crypto_stream.go b/vendor/github.com/lucas-clemente/quic-go/crypto_stream.go index 36e21d330..aa90b15af 100644 --- a/vendor/github.com/lucas-clemente/quic-go/crypto_stream.go +++ b/vendor/github.com/lucas-clemente/quic-go/crypto_stream.go @@ -56,7 +56,7 @@ func (s *cryptoStreamImpl) HandleCryptoFrame(f *wire.CryptoFrame) error { // could e.g. be a retransmission return nil } - s.highestOffset = utils.MaxByteCount(s.highestOffset, highestOffset) + s.highestOffset = utils.Max(s.highestOffset, highestOffset) if err := s.queue.Push(f.Data, f.Offset, nil); err != nil { return err } @@ -107,7 +107,7 @@ func (s *cryptoStreamImpl) HasData() bool { func (s *cryptoStreamImpl) PopCryptoFrame(maxLen protocol.ByteCount) *wire.CryptoFrame { f := &wire.CryptoFrame{Offset: s.writeOffset} - n := utils.MinByteCount(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf))) + n := utils.Min(f.MaxDataLen(maxLen), protocol.ByteCount(len(s.writeBuf))) f.Data = s.writeBuf[:n] s.writeBuf = s.writeBuf[n:] s.writeOffset += n diff --git a/vendor/github.com/lucas-clemente/quic-go/frame_sorter.go b/vendor/github.com/lucas-clemente/quic-go/frame_sorter.go index aeafa7d42..0573ade93 100644 --- a/vendor/github.com/lucas-clemente/quic-go/frame_sorter.go +++ b/vendor/github.com/lucas-clemente/quic-go/frame_sorter.go @@ -4,9 +4,15 @@ import ( "errors" "github.com/lucas-clemente/quic-go/internal/protocol" - "github.com/lucas-clemente/quic-go/internal/utils" + list "github.com/lucas-clemente/quic-go/internal/utils/linkedlist" ) +// byteInterval is an interval from one ByteCount to the other +type byteInterval struct { + Start protocol.ByteCount + End protocol.ByteCount +} + type frameSorterEntry struct { Data []byte DoneCb func() @@ -15,17 +21,17 @@ type frameSorterEntry struct { type frameSorter struct { queue map[protocol.ByteCount]frameSorterEntry readPos protocol.ByteCount - gaps *utils.ByteIntervalList + gaps *list.List[byteInterval] } var errDuplicateStreamData = errors.New("duplicate stream data") func newFrameSorter() *frameSorter { s := frameSorter{ - gaps: utils.NewByteIntervalList(), + gaps: list.New[byteInterval](), queue: make(map[protocol.ByteCount]frameSorterEntry), } - s.gaps.PushFront(utils.ByteInterval{Start: 0, End: protocol.MaxByteCount}) + s.gaps.PushFront(byteInterval{Start: 0, End: protocol.MaxByteCount}) return &s } @@ -118,7 +124,7 @@ func (s *frameSorter) push(data []byte, offset protocol.ByteCount, doneCb func() if !startGapEqualsEndGap { s.deleteConsecutive(startGapEnd) - var nextGap *utils.ByteIntervalElement + var nextGap *list.Element[byteInterval] for gap := startGapNext; gap.Value.End < endGapStart; gap = nextGap { nextGap = gap.Next() s.deleteConsecutive(gap.Value.End) @@ -140,7 +146,7 @@ func (s *frameSorter) push(data []byte, offset protocol.ByteCount, doneCb func() } else { if startGapEqualsEndGap && adjustedStartGapEnd { // The frame split the existing gap into two. - s.gaps.InsertAfter(utils.ByteInterval{Start: end, End: startGapEnd}, startGap) + s.gaps.InsertAfter(byteInterval{Start: end, End: startGapEnd}, startGap) } else if !startGapEqualsEndGap { endGap.Value.Start = end } @@ -164,7 +170,7 @@ func (s *frameSorter) push(data []byte, offset protocol.ByteCount, doneCb func() return nil } -func (s *frameSorter) findStartGap(offset protocol.ByteCount) (*utils.ByteIntervalElement, bool) { +func (s *frameSorter) findStartGap(offset protocol.ByteCount) (*list.Element[byteInterval], bool) { for gap := s.gaps.Front(); gap != nil; gap = gap.Next() { if offset >= gap.Value.Start && offset <= gap.Value.End { return gap, true @@ -176,7 +182,7 @@ func (s *frameSorter) findStartGap(offset protocol.ByteCount) (*utils.ByteInterv panic("no gap found") } -func (s *frameSorter) findEndGap(startGap *utils.ByteIntervalElement, offset protocol.ByteCount) (*utils.ByteIntervalElement, bool) { +func (s *frameSorter) findEndGap(startGap *list.Element[byteInterval], offset protocol.ByteCount) (*list.Element[byteInterval], bool) { for gap := startGap; gap != nil; gap = gap.Next() { if offset >= gap.Value.Start && offset < gap.Value.End { return gap, true diff --git a/vendor/github.com/lucas-clemente/quic-go/interface.go b/vendor/github.com/lucas-clemente/quic-go/interface.go index 6130b5497..c400f9860 100644 --- a/vendor/github.com/lucas-clemente/quic-go/interface.go +++ b/vendor/github.com/lucas-clemente/quic-go/interface.go @@ -26,16 +26,6 @@ const ( Version2 = protocol.Version2 ) -// A Token can be used to verify the ownership of the client address. -type Token struct { - // IsRetryToken encodes how the client received the token. There are two ways: - // * In a Retry packet sent when trying to establish a new connection. - // * In a NEW_TOKEN frame on a previous connection. - IsRetryToken bool - RemoteAddr string - SentTime time.Time -} - // A ClientToken is a token received by the client. // It can be used to skip address validation on future connection attempts. type ClientToken struct { @@ -211,6 +201,24 @@ type EarlyConnection interface { NextConnection() Connection } +// A ConnectionIDGenerator is an interface that allows clients to implement their own format +// for the Connection IDs that servers/clients use as SrcConnectionID in QUIC packets. +// +// Connection IDs generated by an implementation should always produce IDs of constant size. +type ConnectionIDGenerator interface { + // GenerateConnectionID generates a new ConnectionID. + // Generated ConnectionIDs should be unique and observers should not be able to correlate two ConnectionIDs. + GenerateConnectionID() ([]byte, error) + + // ConnectionIDLen tells what is the length of the ConnectionIDs generated by the implementation of + // this interface. + // Effectively, this means that implementations of ConnectionIDGenerator must always return constant-size + // connection IDs. Valid lengths are between 0 and 20 and calls to GenerateConnectionID. + // 0-length ConnectionsIDs can be used when an endpoint (server or client) does not require multiplexing connections + // in the presence of a connection migration environment. + ConnectionIDLen() int +} + // Config contains all configuration data needed for a QUIC server or client. type Config struct { // The QUIC versions that can be negotiated. @@ -223,6 +231,11 @@ type Config struct { // If used for a server, or dialing on a packet conn, a 4 byte connection ID will be used. // When dialing on a packet conn, the ConnectionIDLength value must be the same for every Dial call. ConnectionIDLength int + // An optional ConnectionIDGenerator to be used for ConnectionIDs generated during the lifecycle of a QUIC connection. + // The goal is to give some control on how connection IDs, which can be useful in some scenarios, in particular for servers. + // By default, if not provided, random connection IDs with the length given by ConnectionIDLength is used. + // Otherwise, if one is provided, then ConnectionIDLength is ignored. + ConnectionIDGenerator ConnectionIDGenerator // HandshakeIdleTimeout is the idle timeout before completion of the handshake. // Specifically, if we don't receive any packet from the peer within this time, the connection attempt is aborted. // If this value is zero, the timeout is set to 5 seconds. @@ -233,14 +246,18 @@ type Config struct { // If the timeout is exceeded, the connection is closed. // If this value is zero, the timeout is set to 30 seconds. MaxIdleTimeout time.Duration - // AcceptToken determines if a Token is accepted. - // It is called with token = nil if the client didn't send a token. - // If not set, a default verification function is used: - // * it verifies that the address matches, and - // * if the token is a retry token, that it was issued within the last 5 seconds - // * else, that it was issued within the last 24 hours. - // This option is only valid for the server. - AcceptToken func(clientAddr net.Addr, token *Token) bool + // RequireAddressValidation determines if a QUIC Retry packet is sent. + // This allows the server to verify the client's address, at the cost of increasing the handshake latency by 1 RTT. + // See https://datatracker.ietf.org/doc/html/rfc9000#section-8 for details. + // If not set, every client is forced to prove its remote address. + RequireAddressValidation func(net.Addr) bool + // MaxRetryTokenAge is the maximum age of a Retry token. + // If not set, it defaults to 5 seconds. Only valid for a server. + MaxRetryTokenAge time.Duration + // MaxTokenAge is the maximum age of the token presented during the handshake, + // for tokens that were issued on a previous connection. + // If not set, it defaults to 24 hours. Only valid for a server. + MaxTokenAge time.Duration // The TokenStore stores tokens received from the server. // Tokens are used to skip address validation on future connection attempts. // The key used to store tokens is the ServerName from the tls.Config, if set diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/ackhandler.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/ackhandler.go index 26291321c..2fc9ae4e0 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/ackhandler.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/ackhandler.go @@ -6,16 +6,19 @@ import ( "github.com/lucas-clemente/quic-go/logging" ) -// NewAckHandler creates a new SentPacketHandler and a new ReceivedPacketHandler +// NewAckHandler creates a new SentPacketHandler and a new ReceivedPacketHandler. +// clientAddressValidated indicates whether the address was validated beforehand by an address validation token. +// clientAddressValidated has no effect for a client. func NewAckHandler( initialPacketNumber protocol.PacketNumber, initialMaxDatagramSize protocol.ByteCount, rttStats *utils.RTTStats, + clientAddressValidated bool, pers protocol.Perspective, tracer logging.ConnectionTracer, logger utils.Logger, version protocol.VersionNumber, ) (SentPacketHandler, ReceivedPacketHandler) { - sph := newSentPacketHandler(initialPacketNumber, initialMaxDatagramSize, rttStats, pers, tracer, logger) + sph := newSentPacketHandler(initialPacketNumber, initialMaxDatagramSize, rttStats, clientAddressValidated, pers, tracer, logger) return sph, newReceivedPacketHandler(sph, rttStats, logger, version) } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/gen.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/gen.go deleted file mode 100644 index 32235f81a..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/gen.go +++ /dev/null @@ -1,3 +0,0 @@ -package ackhandler - -//go:generate genny -pkg ackhandler -in ../utils/linkedlist/linkedlist.go -out packet_linkedlist.go gen Item=Packet diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go index 5777d97a7..226bfcbbc 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/interfaces.go @@ -23,6 +23,10 @@ type Packet struct { skippedPacket bool } +func (p *Packet) outstanding() bool { + return !p.declaredLost && !p.skippedPacket && !p.IsPathMTUProbePacket +} + // SentPacketHandler handles ACKs received for outgoing packets type SentPacketHandler interface { // SentPacket may modify the packet diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go index 7d58650cc..b63083bf2 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_number_generator.go @@ -72,5 +72,5 @@ func (p *skippingPacketNumberGenerator) Pop() protocol.PacketNumber { func (p *skippingPacketNumberGenerator) generateNewSkip() { // make sure that there are never two consecutive packet numbers that are skipped p.nextToSkip = p.next + 2 + protocol.PacketNumber(p.rng.Int31n(int32(2*p.period))) - p.period = utils.MinPacketNumber(2*p.period, p.maxPeriod) + p.period = utils.Min(2*p.period, p.maxPeriod) } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_history.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_history.go index 5a0391ef2..ca0b475b2 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_history.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_history.go @@ -2,22 +2,28 @@ package ackhandler import ( "github.com/lucas-clemente/quic-go/internal/protocol" - "github.com/lucas-clemente/quic-go/internal/utils" + list "github.com/lucas-clemente/quic-go/internal/utils/linkedlist" "github.com/lucas-clemente/quic-go/internal/wire" ) +// interval is an interval from one PacketNumber to the other +type interval struct { + Start protocol.PacketNumber + End protocol.PacketNumber +} + // The receivedPacketHistory stores if a packet number has already been received. // It generates ACK ranges which can be used to assemble an ACK frame. // It does not store packet contents. type receivedPacketHistory struct { - ranges *utils.PacketIntervalList + ranges *list.List[interval] deletedBelow protocol.PacketNumber } func newReceivedPacketHistory() *receivedPacketHistory { return &receivedPacketHistory{ - ranges: utils.NewPacketIntervalList(), + ranges: list.New[interval](), } } @@ -34,7 +40,7 @@ func (h *receivedPacketHistory) ReceivedPacket(p protocol.PacketNumber) bool /* func (h *receivedPacketHistory) addToRanges(p protocol.PacketNumber) bool /* is a new packet (and not a duplicate / delayed packet) */ { if h.ranges.Len() == 0 { - h.ranges.PushBack(utils.PacketInterval{Start: p, End: p}) + h.ranges.PushBack(interval{Start: p, End: p}) return true } @@ -61,13 +67,13 @@ func (h *receivedPacketHistory) addToRanges(p protocol.PacketNumber) bool /* is // create a new range at the end if p > el.Value.End { - h.ranges.InsertAfter(utils.PacketInterval{Start: p, End: p}, el) + h.ranges.InsertAfter(interval{Start: p, End: p}, el) return true } } // create a new range at the beginning - h.ranges.InsertBefore(utils.PacketInterval{Start: p, End: p}, h.ranges.Front()) + h.ranges.InsertBefore(interval{Start: p, End: p}, h.ranges.Front()) return true } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_tracker.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_tracker.go index 56e792695..36833f062 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_tracker.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/received_packet_tracker.go @@ -175,7 +175,7 @@ func (h *receivedPacketTracker) GetAckFrame(onlyIfQueued bool) *wire.AckFrame { AckRanges: h.packetHistory.GetAckRanges(), // Make sure that the DelayTime is always positive. // This is not guaranteed on systems that don't have a monotonic clock. - DelayTime: utils.MaxDuration(0, now.Sub(h.largestObservedReceivedTime)), + DelayTime: utils.Max(0, now.Sub(h.largestObservedReceivedTime)), ECT0: h.ect0, ECT1: h.ect1, ECNCE: h.ecnce, diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go index 7df91f23f..5a8cd70e8 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_handler.go @@ -101,10 +101,13 @@ var ( _ sentPacketTracker = &sentPacketHandler{} ) +// clientAddressValidated indicates whether the address was validated beforehand by an address validation token. +// If the address was validated, the amplification limit doesn't apply. It has no effect for a client. func newSentPacketHandler( initialPN protocol.PacketNumber, initialMaxDatagramSize protocol.ByteCount, rttStats *utils.RTTStats, + clientAddressValidated bool, pers protocol.Perspective, tracer logging.ConnectionTracer, logger utils.Logger, @@ -119,7 +122,7 @@ func newSentPacketHandler( return &sentPacketHandler{ peerCompletedAddressValidation: pers == protocol.PerspectiveServer, - peerAddressValidated: pers == protocol.PerspectiveClient, + peerAddressValidated: pers == protocol.PerspectiveClient || clientAddressValidated, initialPackets: newPacketNumberSpace(initialPN, false, rttStats), handshakePackets: newPacketNumberSpace(0, false, rttStats), appDataPackets: newPacketNumberSpace(0, true, rttStats), @@ -256,7 +259,7 @@ func (h *sentPacketHandler) sentPacketImpl(packet *Packet) bool /* is ack-elicit pnSpace := h.getPacketNumberSpace(packet.EncryptionLevel) if h.logger.Debug() && pnSpace.history.HasOutstandingPackets() { - for p := utils.MaxPacketNumber(0, pnSpace.largestSent+1); p < packet.PacketNumber; p++ { + for p := utils.Max(0, pnSpace.largestSent+1); p < packet.PacketNumber; p++ { h.logger.Debugf("Skipping packet number %d", p) } } @@ -288,7 +291,7 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En } } - pnSpace.largestAcked = utils.MaxPacketNumber(pnSpace.largestAcked, largestAcked) + pnSpace.largestAcked = utils.Max(pnSpace.largestAcked, largestAcked) // Servers complete address validation when a protected packet is received. if h.perspective == protocol.PerspectiveClient && !h.peerCompletedAddressValidation && @@ -310,7 +313,7 @@ func (h *sentPacketHandler) ReceivedAck(ack *wire.AckFrame, encLevel protocol.En // don't use the ack delay for Initial and Handshake packets var ackDelay time.Duration if encLevel == protocol.Encryption1RTT { - ackDelay = utils.MinDuration(ack.DelayTime, h.rttStats.MaxAckDelay()) + ackDelay = utils.Min(ack.DelayTime, h.rttStats.MaxAckDelay()) } h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay, rcvTime) if h.logger.Debug() { @@ -406,7 +409,7 @@ func (h *sentPacketHandler) detectAndRemoveAckedPackets(ack *wire.AckFrame, encL for _, p := range h.ackedPackets { if p.LargestAcked != protocol.InvalidPacketNumber && encLevel == protocol.Encryption1RTT { - h.lowestNotConfirmedAcked = utils.MaxPacketNumber(h.lowestNotConfirmedAcked, p.LargestAcked+1) + h.lowestNotConfirmedAcked = utils.Max(h.lowestNotConfirmedAcked, p.LargestAcked+1) } for _, f := range p.Frames { @@ -554,11 +557,11 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E pnSpace := h.getPacketNumberSpace(encLevel) pnSpace.lossTime = time.Time{} - maxRTT := float64(utils.MaxDuration(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT())) + maxRTT := float64(utils.Max(h.rttStats.LatestRTT(), h.rttStats.SmoothedRTT())) lossDelay := time.Duration(timeThreshold * maxRTT) // Minimum time of granularity before packets are deemed lost. - lossDelay = utils.MaxDuration(lossDelay, protocol.TimerGranularity) + lossDelay = utils.Max(lossDelay, protocol.TimerGranularity) // Packets sent before this time are deemed lost. lostSendTime := now.Add(-lossDelay) @@ -598,7 +601,7 @@ func (h *sentPacketHandler) detectLostPackets(now time.Time, encLevel protocol.E pnSpace.lossTime = lossTime } if packetLost { - p.declaredLost = true + p = pnSpace.history.DeclareLost(p) // the bytes in flight need to be reduced no matter if the frames in this packet will be retransmitted h.removeFromBytesInFlight(p) h.queueFramesForRetransmission(p) @@ -767,7 +770,7 @@ func (h *sentPacketHandler) QueueProbePacket(encLevel protocol.EncryptionLevel) // TODO: don't declare the packet lost here. // Keep track of acknowledged frames instead. h.removeFromBytesInFlight(p) - p.declaredLost = true + pnSpace.history.DeclareLost(p) return true } @@ -808,7 +811,7 @@ func (h *sentPacketHandler) ResetForRetry() error { if h.ptoCount == 0 { // Don't set the RTT to a value lower than 5ms here. now := time.Now() - h.rttStats.UpdateRTT(utils.MaxDuration(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now) + h.rttStats.UpdateRTT(utils.Max(minRTTAfterRetry, now.Sub(firstPacketSendTime)), 0, now) if h.logger.Debug() { h.logger.Debugf("\tupdated RTT: %s (σ: %s)", h.rttStats.SmoothedRTT(), h.rttStats.MeanDeviation()) } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go index 36489367d..fca269115 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/sent_packet_history.go @@ -6,21 +6,24 @@ import ( "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/utils" + list "github.com/lucas-clemente/quic-go/internal/utils/linkedlist" ) type sentPacketHistory struct { - rttStats *utils.RTTStats - packetList *PacketList - packetMap map[protocol.PacketNumber]*PacketElement - highestSent protocol.PacketNumber + rttStats *utils.RTTStats + outstandingPacketList *list.List[Packet] + etcPacketList *list.List[Packet] + packetMap map[protocol.PacketNumber]*list.Element[Packet] + highestSent protocol.PacketNumber } func newSentPacketHistory(rttStats *utils.RTTStats) *sentPacketHistory { return &sentPacketHistory{ - rttStats: rttStats, - packetList: NewPacketList(), - packetMap: make(map[protocol.PacketNumber]*PacketElement), - highestSent: protocol.InvalidPacketNumber, + rttStats: rttStats, + outstandingPacketList: list.New[Packet](), + etcPacketList: list.New[Packet](), + packetMap: make(map[protocol.PacketNumber]*list.Element[Packet]), + highestSent: protocol.InvalidPacketNumber, } } @@ -30,7 +33,7 @@ func (h *sentPacketHistory) SentPacket(p *Packet, isAckEliciting bool) { } // Skipped packet numbers. for pn := h.highestSent + 1; pn < p.PacketNumber; pn++ { - el := h.packetList.PushBack(Packet{ + el := h.etcPacketList.PushBack(Packet{ PacketNumber: pn, EncryptionLevel: p.EncryptionLevel, SendTime: p.SendTime, @@ -41,7 +44,12 @@ func (h *sentPacketHistory) SentPacket(p *Packet, isAckEliciting bool) { h.highestSent = p.PacketNumber if isAckEliciting { - el := h.packetList.PushBack(*p) + var el *list.Element[Packet] + if p.outstanding() { + el = h.outstandingPacketList.PushBack(*p) + } else { + el = h.etcPacketList.PushBack(*p) + } h.packetMap[p.PacketNumber] = el } } @@ -49,10 +57,25 @@ func (h *sentPacketHistory) SentPacket(p *Packet, isAckEliciting bool) { // Iterate iterates through all packets. func (h *sentPacketHistory) Iterate(cb func(*Packet) (cont bool, err error)) error { cont := true - var next *PacketElement - for el := h.packetList.Front(); cont && el != nil; el = next { + outstandingEl := h.outstandingPacketList.Front() + etcEl := h.etcPacketList.Front() + var el *list.Element[Packet] + // whichever has the next packet number is returned first + for cont { + if outstandingEl == nil || (etcEl != nil && etcEl.Value.PacketNumber < outstandingEl.Value.PacketNumber) { + el = etcEl + } else { + el = outstandingEl + } + if el == nil { + return nil + } + if el == outstandingEl { + outstandingEl = outstandingEl.Next() + } else { + etcEl = etcEl.Next() + } var err error - next = el.Next() cont, err = cb(&el.Value) if err != nil { return err @@ -61,15 +84,13 @@ func (h *sentPacketHistory) Iterate(cb func(*Packet) (cont bool, err error)) err return nil } -// FirstOutStanding returns the first outstanding packet. +// FirstOutstanding returns the first outstanding packet. func (h *sentPacketHistory) FirstOutstanding() *Packet { - for el := h.packetList.Front(); el != nil; el = el.Next() { - p := &el.Value - if !p.declaredLost && !p.skippedPacket && !p.IsPathMTUProbePacket { - return p - } + el := h.outstandingPacketList.Front() + if el == nil { + return nil } - return nil + return &el.Value } func (h *sentPacketHistory) Len() int { @@ -81,28 +102,53 @@ func (h *sentPacketHistory) Remove(p protocol.PacketNumber) error { if !ok { return fmt.Errorf("packet %d not found in sent packet history", p) } - h.packetList.Remove(el) + h.outstandingPacketList.Remove(el) + h.etcPacketList.Remove(el) delete(h.packetMap, p) return nil } func (h *sentPacketHistory) HasOutstandingPackets() bool { - return h.FirstOutstanding() != nil + return h.outstandingPacketList.Len() > 0 } func (h *sentPacketHistory) DeleteOldPackets(now time.Time) { maxAge := 3 * h.rttStats.PTO(false) - var nextEl *PacketElement - for el := h.packetList.Front(); el != nil; el = nextEl { + var nextEl *list.Element[Packet] + // we don't iterate outstandingPacketList, as we should not delete outstanding packets. + // being outstanding for more than 3*PTO should only happen in the case of drastic RTT changes. + for el := h.etcPacketList.Front(); el != nil; el = nextEl { nextEl = el.Next() p := el.Value if p.SendTime.After(now.Add(-maxAge)) { break } - if !p.skippedPacket && !p.declaredLost { // should only happen in the case of drastic RTT changes - continue - } delete(h.packetMap, p.PacketNumber) - h.packetList.Remove(el) + h.etcPacketList.Remove(el) } } + +func (h *sentPacketHistory) DeclareLost(p *Packet) *Packet { + el, ok := h.packetMap[p.PacketNumber] + if !ok { + return nil + } + // try to remove it from both lists, as we don't know which one it currently belongs to. + // Remove is a no-op for elements that are not in the list. + h.outstandingPacketList.Remove(el) + h.etcPacketList.Remove(el) + p.declaredLost = true + // move it to the correct position in the etc list (based on the packet number) + for el = h.etcPacketList.Back(); el != nil; el = el.Prev() { + if el.Value.PacketNumber < p.PacketNumber { + break + } + } + if el == nil { + el = h.etcPacketList.PushFront(*p) + } else { + el = h.etcPacketList.InsertAfter(*p, el) + } + h.packetMap[p.PacketNumber] = el + return &el.Value +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic.go index beadd627c..a4155b83c 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic.go @@ -187,7 +187,7 @@ func (c *Cubic) CongestionWindowAfterAck( targetCongestionWindow = c.originPointCongestionWindow - deltaCongestionWindow } // Limit the CWND increase to half the acked bytes. - targetCongestionWindow = utils.MinByteCount(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2) + targetCongestionWindow = utils.Min(targetCongestionWindow, currentCongestionWindow+c.ackedBytesCount/2) // Increase the window by approximately Alpha * 1 MSS of bytes every // time we ack an estimated tcp window of bytes. For small diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go index 059b8f6a5..1d17ce225 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/cubic_sender.go @@ -178,7 +178,7 @@ func (c *cubicSender) OnPacketAcked( priorInFlight protocol.ByteCount, eventTime time.Time, ) { - c.largestAckedPacketNumber = utils.MaxPacketNumber(ackedPacketNumber, c.largestAckedPacketNumber) + c.largestAckedPacketNumber = utils.Max(ackedPacketNumber, c.largestAckedPacketNumber) if c.InRecovery() { return } @@ -246,7 +246,7 @@ func (c *cubicSender) maybeIncreaseCwnd( c.numAckedPackets = 0 } } else { - c.congestionWindow = utils.MinByteCount(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime)) + c.congestionWindow = utils.Min(c.maxCongestionWindow(), c.cubic.CongestionWindowAfterAck(ackedBytes, c.congestionWindow, c.rttStats.MinRTT(), eventTime)) } } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/hybrid_slow_start.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/hybrid_slow_start.go index b5ae3d5eb..0088d7e87 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/hybrid_slow_start.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/hybrid_slow_start.go @@ -75,8 +75,8 @@ func (s *HybridSlowStart) ShouldExitSlowStart(latestRTT time.Duration, minRTT ti // Divide minRTT by 8 to get a rtt increase threshold for exiting. minRTTincreaseThresholdUs := int64(minRTT / time.Microsecond >> hybridStartDelayFactorExp) // Ensure the rtt threshold is never less than 2ms or more than 16ms. - minRTTincreaseThresholdUs = utils.MinInt64(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs) - minRTTincreaseThreshold := time.Duration(utils.MaxInt64(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond + minRTTincreaseThresholdUs = utils.Min(minRTTincreaseThresholdUs, hybridStartDelayMaxThresholdUs) + minRTTincreaseThreshold := time.Duration(utils.Max(minRTTincreaseThresholdUs, hybridStartDelayMinThresholdUs)) * time.Microsecond if s.currentMinRTT > (minRTT + minRTTincreaseThreshold) { s.hystartFound = true diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/pacer.go b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/pacer.go index 7ec4d8f57..6561a32ca 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/congestion/pacer.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/congestion/pacer.go @@ -50,11 +50,11 @@ func (p *pacer) Budget(now time.Time) protocol.ByteCount { return p.maxBurstSize() } budget := p.budgetAtLastSent + (protocol.ByteCount(p.getAdjustedBandwidth())*protocol.ByteCount(now.Sub(p.lastSentTime).Nanoseconds()))/1e9 - return utils.MinByteCount(p.maxBurstSize(), budget) + return utils.Min(p.maxBurstSize(), budget) } func (p *pacer) maxBurstSize() protocol.ByteCount { - return utils.MaxByteCount( + return utils.Max( protocol.ByteCount(uint64((protocol.MinPacingDelay+protocol.TimerGranularity).Nanoseconds())*p.getAdjustedBandwidth())/1e9, maxBurstSizePackets*p.maxDatagramSize, ) @@ -66,7 +66,7 @@ func (p *pacer) TimeUntilSend() time.Time { if p.budgetAtLastSent >= p.maxDatagramSize { return time.Time{} } - return p.lastSentTime.Add(utils.MaxDuration( + return p.lastSentTime.Add(utils.Max( protocol.MinPacingDelay, time.Duration(math.Ceil(float64(p.maxDatagramSize-p.budgetAtLastSent)*1e9/float64(p.getAdjustedBandwidth())))*time.Nanosecond, )) diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/base_flow_controller.go b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/base_flow_controller.go index 2bf14fdc0..675b7e4d8 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/base_flow_controller.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/base_flow_controller.go @@ -107,7 +107,7 @@ func (c *baseFlowController) maybeAdjustWindowSize() { now := time.Now() if now.Sub(c.epochStartTime) < time.Duration(4*fraction*float64(rtt)) { // window is consumed too fast, try to increase the window size - newSize := utils.MinByteCount(2*c.receiveWindowSize, c.maxReceiveWindowSize) + newSize := utils.Min(2*c.receiveWindowSize, c.maxReceiveWindowSize) if newSize > c.receiveWindowSize && (c.allowWindowIncrease == nil || c.allowWindowIncrease(newSize-c.receiveWindowSize)) { c.receiveWindowSize = newSize } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/connection_flow_controller.go b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/connection_flow_controller.go index 6bf2241b9..dbd3973ee 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/connection_flow_controller.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/connection_flow_controller.go @@ -87,7 +87,7 @@ func (c *connectionFlowController) EnsureMinimumWindowSize(inc protocol.ByteCoun c.mutex.Lock() if inc > c.receiveWindowSize { c.logger.Debugf("Increasing receive flow control window for the connection to %d kB, in response to stream flow control window increase", c.receiveWindowSize/(1<<10)) - newSize := utils.MinByteCount(inc, c.maxReceiveWindowSize) + newSize := utils.Min(inc, c.maxReceiveWindowSize) if delta := newSize - c.receiveWindowSize; delta > 0 && c.allowWindowIncrease(delta) { c.receiveWindowSize = newSize } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/stream_flow_controller.go b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/stream_flow_controller.go index aa66aef1a..d9bf649ac 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/stream_flow_controller.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/flowcontrol/stream_flow_controller.go @@ -123,7 +123,7 @@ func (c *streamFlowController) AddBytesSent(n protocol.ByteCount) { } func (c *streamFlowController) SendWindowSize() protocol.ByteCount { - return utils.MinByteCount(c.baseFlowController.sendWindowSize(), c.connection.SendWindowSize()) + return utils.Min(c.baseFlowController.sendWindowSize(), c.connection.SendWindowSize()) } func (c *streamFlowController) shouldQueueWindowUpdate() bool { diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/aead.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/aead.go index 03b039289..35e3dcf18 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/aead.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/aead.go @@ -83,7 +83,7 @@ func (o *longHeaderOpener) Open(dst, src []byte, pn protocol.PacketNumber, ad [] // It uses the nonce provided here and XOR it with the IV. dec, err := o.aead.Open(dst, o.nonceBuf, src, ad) if err == nil { - o.highestRcvdPN = utils.MaxPacketNumber(o.highestRcvdPN, pn) + o.highestRcvdPN = utils.Max(o.highestRcvdPN, pn) } else { err = ErrDecryptionFailed } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/token_generator.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/token_generator.go index 2df5fcd8c..a8dda91e6 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/token_generator.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/token_generator.go @@ -1,6 +1,7 @@ package handshake import ( + "bytes" "encoding/asn1" "fmt" "io" @@ -17,14 +18,19 @@ const ( // A Token is derived from the client address and can be used to verify the ownership of this address. type Token struct { - IsRetryToken bool - RemoteAddr string - SentTime time.Time + IsRetryToken bool + SentTime time.Time + encodedRemoteAddr []byte // only set for retry tokens OriginalDestConnectionID protocol.ConnectionID RetrySrcConnectionID protocol.ConnectionID } +// ValidateRemoteAddr validates the address, but does not check expiration +func (t *Token) ValidateRemoteAddr(addr net.Addr) bool { + return bytes.Equal(encodeRemoteAddr(addr), t.encodedRemoteAddr) +} + // token is the struct that is used for ASN1 serialization and deserialization type token struct { IsRetryToken bool @@ -101,9 +107,9 @@ func (g *TokenGenerator) DecodeToken(encrypted []byte) (*Token, error) { return nil, fmt.Errorf("rest when unpacking token: %d", len(rest)) } token := &Token{ - IsRetryToken: t.IsRetryToken, - RemoteAddr: decodeRemoteAddr(t.RemoteAddr), - SentTime: time.Unix(0, t.Timestamp), + IsRetryToken: t.IsRetryToken, + SentTime: time.Unix(0, t.Timestamp), + encodedRemoteAddr: t.RemoteAddr, } if t.IsRetryToken { token.OriginalDestConnectionID = protocol.ConnectionID(t.OriginalDestConnectionID) @@ -119,16 +125,3 @@ func encodeRemoteAddr(remoteAddr net.Addr) []byte { } return append([]byte{tokenPrefixString}, []byte(remoteAddr.String())...) } - -// decodeRemoteAddr decodes the remote address saved in the token -func decodeRemoteAddr(data []byte) string { - // data will never be empty for a token that we generated. - // Check it to be on the safe side - if len(data) == 0 { - return "" - } - if data[0] == tokenPrefixIP { - return net.IP(data[1:]).String() - } - return string(data[1:]) -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/updatable_aead.go b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/updatable_aead.go index 1532e7b5a..4093a206c 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/handshake/updatable_aead.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/handshake/updatable_aead.go @@ -169,7 +169,7 @@ func (a *updatableAEAD) Open(dst, src []byte, rcvTime time.Time, pn protocol.Pac } } if err == nil { - a.highestRcvdPN = utils.MaxPacketNumber(a.highestRcvdPN, pn) + a.highestRcvdPN = utils.Max(a.highestRcvdPN, pn) } return dec, err } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/connection_id.go b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/connection_id.go index 3aec2cd38..7ae7d9dcf 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/protocol/connection_id.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/protocol/connection_id.go @@ -67,3 +67,15 @@ func (c ConnectionID) String() string { } return fmt.Sprintf("%x", c.Bytes()) } + +type DefaultConnectionIDGenerator struct { + ConnLen int +} + +func (d *DefaultConnectionIDGenerator) GenerateConnectionID() ([]byte, error) { + return GenerateConnectionID(d.ConnLen) +} + +func (d *DefaultConnectionIDGenerator) ConnectionIDLen() int { + return d.ConnLen +} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go116.go b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go116.go deleted file mode 100644 index e3024624c..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go116.go +++ /dev/null @@ -1,100 +0,0 @@ -//go:build go1.16 && !go1.17 -// +build go1.16,!go1.17 - -package qtls - -import ( - "crypto" - "crypto/cipher" - "crypto/tls" - "net" - "unsafe" - - "github.com/marten-seemann/qtls-go1-16" -) - -type ( - // Alert is a TLS alert - Alert = qtls.Alert - // A Certificate is qtls.Certificate. - Certificate = qtls.Certificate - // CertificateRequestInfo contains inforamtion about a certificate request. - CertificateRequestInfo = qtls.CertificateRequestInfo - // A CipherSuiteTLS13 is a cipher suite for TLS 1.3 - CipherSuiteTLS13 = qtls.CipherSuiteTLS13 - // ClientHelloInfo contains information about a ClientHello. - ClientHelloInfo = qtls.ClientHelloInfo - // ClientSessionCache is a cache used for session resumption. - ClientSessionCache = qtls.ClientSessionCache - // ClientSessionState is a state needed for session resumption. - ClientSessionState = qtls.ClientSessionState - // A Config is a qtls.Config. - Config = qtls.Config - // A Conn is a qtls.Conn. - Conn = qtls.Conn - // ConnectionState contains information about the state of the connection. - ConnectionState = qtls.ConnectionStateWith0RTT - // EncryptionLevel is the encryption level of a message. - EncryptionLevel = qtls.EncryptionLevel - // Extension is a TLS extension - Extension = qtls.Extension - // ExtraConfig is the qtls.ExtraConfig - ExtraConfig = qtls.ExtraConfig - // RecordLayer is a qtls RecordLayer. - RecordLayer = qtls.RecordLayer -) - -const ( - // EncryptionHandshake is the Handshake encryption level - EncryptionHandshake = qtls.EncryptionHandshake - // Encryption0RTT is the 0-RTT encryption level - Encryption0RTT = qtls.Encryption0RTT - // EncryptionApplication is the application data encryption level - EncryptionApplication = qtls.EncryptionApplication -) - -// AEADAESGCMTLS13 creates a new AES-GCM AEAD for TLS 1.3 -func AEADAESGCMTLS13(key, fixedNonce []byte) cipher.AEAD { - return qtls.AEADAESGCMTLS13(key, fixedNonce) -} - -// Client returns a new TLS client side connection. -func Client(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - return qtls.Client(conn, config, extraConfig) -} - -// Server returns a new TLS server side connection. -func Server(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - return qtls.Server(conn, config, extraConfig) -} - -func GetConnectionState(conn *Conn) ConnectionState { - return conn.ConnectionStateWith0RTT() -} - -// ToTLSConnectionState extracts the tls.ConnectionState -func ToTLSConnectionState(cs ConnectionState) tls.ConnectionState { - return cs.ConnectionState -} - -type cipherSuiteTLS13 struct { - ID uint16 - KeyLen int - AEAD func(key, fixedNonce []byte) cipher.AEAD - Hash crypto.Hash -} - -//go:linkname cipherSuiteTLS13ByID github.com/marten-seemann/qtls-go1-16.cipherSuiteTLS13ByID -func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 - -// CipherSuiteTLS13ByID gets a TLS 1.3 cipher suite. -func CipherSuiteTLS13ByID(id uint16) *CipherSuiteTLS13 { - val := cipherSuiteTLS13ByID(id) - cs := (*cipherSuiteTLS13)(unsafe.Pointer(val)) - return &qtls.CipherSuiteTLS13{ - ID: cs.ID, - KeyLen: cs.KeyLen, - AEAD: cs.AEAD, - Hash: cs.Hash, - } -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go117.go b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go117.go deleted file mode 100644 index bc385f194..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go117.go +++ /dev/null @@ -1,100 +0,0 @@ -//go:build go1.17 && !go1.18 -// +build go1.17,!go1.18 - -package qtls - -import ( - "crypto" - "crypto/cipher" - "crypto/tls" - "net" - "unsafe" - - "github.com/marten-seemann/qtls-go1-17" -) - -type ( - // Alert is a TLS alert - Alert = qtls.Alert - // A Certificate is qtls.Certificate. - Certificate = qtls.Certificate - // CertificateRequestInfo contains inforamtion about a certificate request. - CertificateRequestInfo = qtls.CertificateRequestInfo - // A CipherSuiteTLS13 is a cipher suite for TLS 1.3 - CipherSuiteTLS13 = qtls.CipherSuiteTLS13 - // ClientHelloInfo contains information about a ClientHello. - ClientHelloInfo = qtls.ClientHelloInfo - // ClientSessionCache is a cache used for session resumption. - ClientSessionCache = qtls.ClientSessionCache - // ClientSessionState is a state needed for session resumption. - ClientSessionState = qtls.ClientSessionState - // A Config is a qtls.Config. - Config = qtls.Config - // A Conn is a qtls.Conn. - Conn = qtls.Conn - // ConnectionState contains information about the state of the connection. - ConnectionState = qtls.ConnectionStateWith0RTT - // EncryptionLevel is the encryption level of a message. - EncryptionLevel = qtls.EncryptionLevel - // Extension is a TLS extension - Extension = qtls.Extension - // ExtraConfig is the qtls.ExtraConfig - ExtraConfig = qtls.ExtraConfig - // RecordLayer is a qtls RecordLayer. - RecordLayer = qtls.RecordLayer -) - -const ( - // EncryptionHandshake is the Handshake encryption level - EncryptionHandshake = qtls.EncryptionHandshake - // Encryption0RTT is the 0-RTT encryption level - Encryption0RTT = qtls.Encryption0RTT - // EncryptionApplication is the application data encryption level - EncryptionApplication = qtls.EncryptionApplication -) - -// AEADAESGCMTLS13 creates a new AES-GCM AEAD for TLS 1.3 -func AEADAESGCMTLS13(key, fixedNonce []byte) cipher.AEAD { - return qtls.AEADAESGCMTLS13(key, fixedNonce) -} - -// Client returns a new TLS client side connection. -func Client(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - return qtls.Client(conn, config, extraConfig) -} - -// Server returns a new TLS server side connection. -func Server(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - return qtls.Server(conn, config, extraConfig) -} - -func GetConnectionState(conn *Conn) ConnectionState { - return conn.ConnectionStateWith0RTT() -} - -// ToTLSConnectionState extracts the tls.ConnectionState -func ToTLSConnectionState(cs ConnectionState) tls.ConnectionState { - return cs.ConnectionState -} - -type cipherSuiteTLS13 struct { - ID uint16 - KeyLen int - AEAD func(key, fixedNonce []byte) cipher.AEAD - Hash crypto.Hash -} - -//go:linkname cipherSuiteTLS13ByID github.com/marten-seemann/qtls-go1-17.cipherSuiteTLS13ByID -func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 - -// CipherSuiteTLS13ByID gets a TLS 1.3 cipher suite. -func CipherSuiteTLS13ByID(id uint16) *CipherSuiteTLS13 { - val := cipherSuiteTLS13ByID(id) - cs := (*cipherSuiteTLS13)(unsafe.Pointer(val)) - return &qtls.CipherSuiteTLS13{ - ID: cs.ID, - KeyLen: cs.KeyLen, - AEAD: cs.AEAD, - Hash: cs.Hash, - } -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go118.go b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go118.go index 5de030c78..e02de3806 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go118.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go118.go @@ -1,5 +1,4 @@ //go:build go1.18 && !go1.19 -// +build go1.18,!go1.19 package qtls diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go119.go b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go119.go index 86dcaea3d..9794b8723 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go119.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go119.go @@ -1,5 +1,4 @@ //go:build go1.19 -// +build go1.19 package qtls diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go120.go b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go120.go index f8d59d8bb..f35538729 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go120.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go120.go @@ -1,5 +1,4 @@ //go:build go1.20 -// +build go1.20 package qtls diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go_oldversion.go b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go_oldversion.go index 384d719c6..83418e9e8 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go_oldversion.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/qtls/go_oldversion.go @@ -1,6 +1,4 @@ -//go:build (go1.9 || go1.10 || go1.11 || go1.12 || go1.13 || go1.14 || go1.15) && !go1.16 -// +build go1.9 go1.10 go1.11 go1.12 go1.13 go1.14 go1.15 -// +build !go1.16 +//go:build !go1.18 package qtls diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteinterval_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteinterval_linkedlist.go deleted file mode 100644 index 096023ef2..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/byteinterval_linkedlist.go +++ /dev/null @@ -1,217 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package utils - -// Linked list implementation from the Go standard library. - -// ByteIntervalElement is an element of a linked list. -type ByteIntervalElement struct { - // Next and previous pointers in the doubly-linked list of elements. - // To simplify the implementation, internally a list l is implemented - // as a ring, such that &l.root is both the next element of the last - // list element (l.Back()) and the previous element of the first list - // element (l.Front()). - next, prev *ByteIntervalElement - - // The list to which this element belongs. - list *ByteIntervalList - - // The value stored with this element. - Value ByteInterval -} - -// Next returns the next list element or nil. -func (e *ByteIntervalElement) Next() *ByteIntervalElement { - if p := e.next; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// Prev returns the previous list element or nil. -func (e *ByteIntervalElement) Prev() *ByteIntervalElement { - if p := e.prev; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// ByteIntervalList is a linked list of ByteIntervals. -type ByteIntervalList struct { - root ByteIntervalElement // sentinel list element, only &root, root.prev, and root.next are used - len int // current list length excluding (this) sentinel element -} - -// Init initializes or clears list l. -func (l *ByteIntervalList) Init() *ByteIntervalList { - l.root.next = &l.root - l.root.prev = &l.root - l.len = 0 - return l -} - -// NewByteIntervalList returns an initialized list. -func NewByteIntervalList() *ByteIntervalList { return new(ByteIntervalList).Init() } - -// Len returns the number of elements of list l. -// The complexity is O(1). -func (l *ByteIntervalList) Len() int { return l.len } - -// Front returns the first element of list l or nil if the list is empty. -func (l *ByteIntervalList) Front() *ByteIntervalElement { - if l.len == 0 { - return nil - } - return l.root.next -} - -// Back returns the last element of list l or nil if the list is empty. -func (l *ByteIntervalList) Back() *ByteIntervalElement { - if l.len == 0 { - return nil - } - return l.root.prev -} - -// lazyInit lazily initializes a zero List value. -func (l *ByteIntervalList) lazyInit() { - if l.root.next == nil { - l.Init() - } -} - -// insert inserts e after at, increments l.len, and returns e. -func (l *ByteIntervalList) insert(e, at *ByteIntervalElement) *ByteIntervalElement { - n := at.next - at.next = e - e.prev = at - e.next = n - n.prev = e - e.list = l - l.len++ - return e -} - -// insertValue is a convenience wrapper for insert(&Element{Value: v}, at). -func (l *ByteIntervalList) insertValue(v ByteInterval, at *ByteIntervalElement) *ByteIntervalElement { - return l.insert(&ByteIntervalElement{Value: v}, at) -} - -// remove removes e from its list, decrements l.len, and returns e. -func (l *ByteIntervalList) remove(e *ByteIntervalElement) *ByteIntervalElement { - e.prev.next = e.next - e.next.prev = e.prev - e.next = nil // avoid memory leaks - e.prev = nil // avoid memory leaks - e.list = nil - l.len-- - return e -} - -// Remove removes e from l if e is an element of list l. -// It returns the element value e.Value. -// The element must not be nil. -func (l *ByteIntervalList) Remove(e *ByteIntervalElement) ByteInterval { - if e.list == l { - // if e.list == l, l must have been initialized when e was inserted - // in l or l == nil (e is a zero Element) and l.remove will crash - l.remove(e) - } - return e.Value -} - -// PushFront inserts a new element e with value v at the front of list l and returns e. -func (l *ByteIntervalList) PushFront(v ByteInterval) *ByteIntervalElement { - l.lazyInit() - return l.insertValue(v, &l.root) -} - -// PushBack inserts a new element e with value v at the back of list l and returns e. -func (l *ByteIntervalList) PushBack(v ByteInterval) *ByteIntervalElement { - l.lazyInit() - return l.insertValue(v, l.root.prev) -} - -// InsertBefore inserts a new element e with value v immediately before mark and returns e. -// If mark is not an element of l, the list is not modified. -// The mark must not be nil. -func (l *ByteIntervalList) InsertBefore(v ByteInterval, mark *ByteIntervalElement) *ByteIntervalElement { - if mark.list != l { - return nil - } - // see comment in List.Remove about initialization of l - return l.insertValue(v, mark.prev) -} - -// InsertAfter inserts a new element e with value v immediately after mark and returns e. -// If mark is not an element of l, the list is not modified. -// The mark must not be nil. -func (l *ByteIntervalList) InsertAfter(v ByteInterval, mark *ByteIntervalElement) *ByteIntervalElement { - if mark.list != l { - return nil - } - // see comment in List.Remove about initialization of l - return l.insertValue(v, mark) -} - -// MoveToFront moves element e to the front of list l. -// If e is not an element of l, the list is not modified. -// The element must not be nil. -func (l *ByteIntervalList) MoveToFront(e *ByteIntervalElement) { - if e.list != l || l.root.next == e { - return - } - // see comment in List.Remove about initialization of l - l.insert(l.remove(e), &l.root) -} - -// MoveToBack moves element e to the back of list l. -// If e is not an element of l, the list is not modified. -// The element must not be nil. -func (l *ByteIntervalList) MoveToBack(e *ByteIntervalElement) { - if e.list != l || l.root.prev == e { - return - } - // see comment in List.Remove about initialization of l - l.insert(l.remove(e), l.root.prev) -} - -// MoveBefore moves element e to its new position before mark. -// If e or mark is not an element of l, or e == mark, the list is not modified. -// The element and mark must not be nil. -func (l *ByteIntervalList) MoveBefore(e, mark *ByteIntervalElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark.prev) -} - -// MoveAfter moves element e to its new position after mark. -// If e or mark is not an element of l, or e == mark, the list is not modified. -// The element and mark must not be nil. -func (l *ByteIntervalList) MoveAfter(e, mark *ByteIntervalElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark) -} - -// PushBackList inserts a copy of an other list at the back of list l. -// The lists l and other may be the same. They must not be nil. -func (l *ByteIntervalList) PushBackList(other *ByteIntervalList) { - l.lazyInit() - for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { - l.insertValue(e.Value, l.root.prev) - } -} - -// PushFrontList inserts a copy of an other list at the front of list l. -// The lists l and other may be the same. They must not be nil. -func (l *ByteIntervalList) PushFrontList(other *ByteIntervalList) { - l.lazyInit() - for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { - l.insertValue(e.Value, &l.root) - } -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/gen.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/gen.go deleted file mode 100644 index 8a63e9589..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/gen.go +++ /dev/null @@ -1,5 +0,0 @@ -package utils - -//go:generate genny -pkg utils -in linkedlist/linkedlist.go -out byteinterval_linkedlist.go gen Item=ByteInterval -//go:generate genny -pkg utils -in linkedlist/linkedlist.go -out packetinterval_linkedlist.go gen Item=PacketInterval -//go:generate genny -pkg utils -in linkedlist/linkedlist.go -out newconnectionid_linkedlist.go gen Item=NewConnectionID diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/linkedlist/README.md b/vendor/github.com/lucas-clemente/quic-go/internal/utils/linkedlist/README.md new file mode 100644 index 000000000..2915d6013 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/linkedlist/README.md @@ -0,0 +1,4 @@ +# Usage + +This is the Go standard library implementation of a linked list +(https://golang.org/src/container/list/list.go), modified to use Go generics. diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/linkedlist/linkedlist.go similarity index 62% rename from vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_linkedlist.go rename to vendor/github.com/lucas-clemente/quic-go/internal/utils/linkedlist/linkedlist.go index bb74f4ef9..217b21efb 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/ackhandler/packet_linkedlist.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/linkedlist/linkedlist.go @@ -1,29 +1,34 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny +// 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 ackhandler +// Package list implements a doubly linked list. +// +// To iterate over a list (where l is a *List[T]): +// +// for e := l.Front(); e != nil; e = e.Next() { +// // do something with e.Value +// } +package list -// Linked list implementation from the Go standard library. - -// PacketElement is an element of a linked list. -type PacketElement struct { +// Element is an element of a linked list. +type Element[T any] struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last // list element (l.Back()) and the previous element of the first list // element (l.Front()). - next, prev *PacketElement + next, prev *Element[T] // The list to which this element belongs. - list *PacketList + list *List[T] // The value stored with this element. - Value Packet + Value T } // Next returns the next list element or nil. -func (e *PacketElement) Next() *PacketElement { +func (e *Element[T]) Next() *Element[T] { if p := e.next; e.list != nil && p != &e.list.root { return p } @@ -31,36 +36,37 @@ func (e *PacketElement) Next() *PacketElement { } // Prev returns the previous list element or nil. -func (e *PacketElement) Prev() *PacketElement { +func (e *Element[T]) Prev() *Element[T] { if p := e.prev; e.list != nil && p != &e.list.root { return p } return nil } -// PacketList is a linked list of Packets. -type PacketList struct { - root PacketElement // sentinel list element, only &root, root.prev, and root.next are used - len int // current list length excluding (this) sentinel element +// List represents a doubly linked list. +// The zero value for List is an empty list ready to use. +type List[T any] struct { + root Element[T] // sentinel list element, only &root, root.prev, and root.next are used + len int // current list length excluding (this) sentinel element } // Init initializes or clears list l. -func (l *PacketList) Init() *PacketList { +func (l *List[T]) Init() *List[T] { l.root.next = &l.root l.root.prev = &l.root l.len = 0 return l } -// NewPacketList returns an initialized list. -func NewPacketList() *PacketList { return new(PacketList).Init() } +// New returns an initialized list. +func New[T any]() *List[T] { return new(List[T]).Init() } // Len returns the number of elements of list l. // The complexity is O(1). -func (l *PacketList) Len() int { return l.len } +func (l *List[T]) Len() int { return l.len } // Front returns the first element of list l or nil if the list is empty. -func (l *PacketList) Front() *PacketElement { +func (l *List[T]) Front() *Element[T] { if l.len == 0 { return nil } @@ -68,7 +74,7 @@ func (l *PacketList) Front() *PacketElement { } // Back returns the last element of list l or nil if the list is empty. -func (l *PacketList) Back() *PacketElement { +func (l *List[T]) Back() *Element[T] { if l.len == 0 { return nil } @@ -76,44 +82,56 @@ func (l *PacketList) Back() *PacketElement { } // lazyInit lazily initializes a zero List value. -func (l *PacketList) lazyInit() { +func (l *List[T]) lazyInit() { if l.root.next == nil { l.Init() } } // insert inserts e after at, increments l.len, and returns e. -func (l *PacketList) insert(e, at *PacketElement) *PacketElement { - n := at.next - at.next = e +func (l *List[T]) insert(e, at *Element[T]) *Element[T] { e.prev = at - e.next = n - n.prev = e + e.next = at.next + e.prev.next = e + e.next.prev = e e.list = l l.len++ return e } // insertValue is a convenience wrapper for insert(&Element{Value: v}, at). -func (l *PacketList) insertValue(v Packet, at *PacketElement) *PacketElement { - return l.insert(&PacketElement{Value: v}, at) +func (l *List[T]) insertValue(v T, at *Element[T]) *Element[T] { + return l.insert(&Element[T]{Value: v}, at) } -// remove removes e from its list, decrements l.len, and returns e. -func (l *PacketList) remove(e *PacketElement) *PacketElement { +// remove removes e from its list, decrements l.len +func (l *List[T]) remove(e *Element[T]) { e.prev.next = e.next e.next.prev = e.prev e.next = nil // avoid memory leaks e.prev = nil // avoid memory leaks e.list = nil l.len-- - return e +} + +// move moves e to next to at. +func (l *List[T]) move(e, at *Element[T]) { + if e == at { + return + } + e.prev.next = e.next + e.next.prev = e.prev + + e.prev = at + e.next = at.next + e.prev.next = e + e.next.prev = e } // Remove removes e from l if e is an element of list l. // It returns the element value e.Value. // The element must not be nil. -func (l *PacketList) Remove(e *PacketElement) Packet { +func (l *List[T]) Remove(e *Element[T]) T { if e.list == l { // if e.list == l, l must have been initialized when e was inserted // in l or l == nil (e is a zero Element) and l.remove will crash @@ -123,13 +141,13 @@ func (l *PacketList) Remove(e *PacketElement) Packet { } // PushFront inserts a new element e with value v at the front of list l and returns e. -func (l *PacketList) PushFront(v Packet) *PacketElement { +func (l *List[T]) PushFront(v T) *Element[T] { l.lazyInit() return l.insertValue(v, &l.root) } // PushBack inserts a new element e with value v at the back of list l and returns e. -func (l *PacketList) PushBack(v Packet) *PacketElement { +func (l *List[T]) PushBack(v T) *Element[T] { l.lazyInit() return l.insertValue(v, l.root.prev) } @@ -137,7 +155,7 @@ func (l *PacketList) PushBack(v Packet) *PacketElement { // InsertBefore inserts a new element e with value v immediately before mark and returns e. // If mark is not an element of l, the list is not modified. // The mark must not be nil. -func (l *PacketList) InsertBefore(v Packet, mark *PacketElement) *PacketElement { +func (l *List[T]) InsertBefore(v T, mark *Element[T]) *Element[T] { if mark.list != l { return nil } @@ -148,7 +166,7 @@ func (l *PacketList) InsertBefore(v Packet, mark *PacketElement) *PacketElement // InsertAfter inserts a new element e with value v immediately after mark and returns e. // If mark is not an element of l, the list is not modified. // The mark must not be nil. -func (l *PacketList) InsertAfter(v Packet, mark *PacketElement) *PacketElement { +func (l *List[T]) InsertAfter(v T, mark *Element[T]) *Element[T] { if mark.list != l { return nil } @@ -159,57 +177,57 @@ func (l *PacketList) InsertAfter(v Packet, mark *PacketElement) *PacketElement { // MoveToFront moves element e to the front of list l. // If e is not an element of l, the list is not modified. // The element must not be nil. -func (l *PacketList) MoveToFront(e *PacketElement) { +func (l *List[T]) MoveToFront(e *Element[T]) { if e.list != l || l.root.next == e { return } // see comment in List.Remove about initialization of l - l.insert(l.remove(e), &l.root) + l.move(e, &l.root) } // MoveToBack moves element e to the back of list l. // If e is not an element of l, the list is not modified. // The element must not be nil. -func (l *PacketList) MoveToBack(e *PacketElement) { +func (l *List[T]) MoveToBack(e *Element[T]) { if e.list != l || l.root.prev == e { return } // see comment in List.Remove about initialization of l - l.insert(l.remove(e), l.root.prev) + l.move(e, l.root.prev) } // MoveBefore moves element e to its new position before mark. // If e or mark is not an element of l, or e == mark, the list is not modified. // The element and mark must not be nil. -func (l *PacketList) MoveBefore(e, mark *PacketElement) { +func (l *List[T]) MoveBefore(e, mark *Element[T]) { if e.list != l || e == mark || mark.list != l { return } - l.insert(l.remove(e), mark.prev) + l.move(e, mark.prev) } // MoveAfter moves element e to its new position after mark. // If e or mark is not an element of l, or e == mark, the list is not modified. // The element and mark must not be nil. -func (l *PacketList) MoveAfter(e, mark *PacketElement) { +func (l *List[T]) MoveAfter(e, mark *Element[T]) { if e.list != l || e == mark || mark.list != l { return } - l.insert(l.remove(e), mark) + l.move(e, mark) } -// PushBackList inserts a copy of an other list at the back of list l. +// PushBackList inserts a copy of another list at the back of list l. // The lists l and other may be the same. They must not be nil. -func (l *PacketList) PushBackList(other *PacketList) { +func (l *List[T]) PushBackList(other *List[T]) { l.lazyInit() for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { l.insertValue(e.Value, l.root.prev) } } -// PushFrontList inserts a copy of an other list at the front of list l. +// PushFrontList inserts a copy of another list at the front of list l. // The lists l and other may be the same. They must not be nil. -func (l *PacketList) PushFrontList(other *PacketList) { +func (l *List[T]) PushFrontList(other *List[T]) { l.lazyInit() for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { l.insertValue(e.Value, &l.root) diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/minmax.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/minmax.go index ee1f85f62..d191f7515 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/minmax.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/minmax.go @@ -4,108 +4,26 @@ import ( "math" "time" - "github.com/lucas-clemente/quic-go/internal/protocol" + "golang.org/x/exp/constraints" ) // InfDuration is a duration of infinite length const InfDuration = time.Duration(math.MaxInt64) -// Max returns the maximum of two Ints -func Max(a, b int) int { +func Max[T constraints.Ordered](a, b T) T { if a < b { return b } return a } -// MaxUint32 returns the maximum of two uint32 -func MaxUint32(a, b uint32) uint32 { - if a < b { - return b - } - return a -} - -// MaxUint64 returns the maximum of two uint64 -func MaxUint64(a, b uint64) uint64 { - if a < b { - return b - } - return a -} - -// MinUint64 returns the maximum of two uint64 -func MinUint64(a, b uint64) uint64 { +func Min[T constraints.Ordered](a, b T) T { if a < b { return a } return b } -// Min returns the minimum of two Ints -func Min(a, b int) int { - if a < b { - return a - } - return b -} - -// MinUint32 returns the maximum of two uint32 -func MinUint32(a, b uint32) uint32 { - if a < b { - return a - } - return b -} - -// MinInt64 returns the minimum of two int64 -func MinInt64(a, b int64) int64 { - if a < b { - return a - } - return b -} - -// MaxInt64 returns the minimum of two int64 -func MaxInt64(a, b int64) int64 { - if a > b { - return a - } - return b -} - -// MinByteCount returns the minimum of two ByteCounts -func MinByteCount(a, b protocol.ByteCount) protocol.ByteCount { - if a < b { - return a - } - return b -} - -// MaxByteCount returns the maximum of two ByteCounts -func MaxByteCount(a, b protocol.ByteCount) protocol.ByteCount { - if a < b { - return b - } - return a -} - -// MaxDuration returns the max duration -func MaxDuration(a, b time.Duration) time.Duration { - if a > b { - return a - } - return b -} - -// MinDuration returns the minimum duration -func MinDuration(a, b time.Duration) time.Duration { - if a > b { - return b - } - return a -} - // MinNonZeroDuration return the minimum duration that's not zero. func MinNonZeroDuration(a, b time.Duration) time.Duration { if a == 0 { @@ -114,7 +32,7 @@ func MinNonZeroDuration(a, b time.Duration) time.Duration { if b == 0 { return a } - return MinDuration(a, b) + return Min(a, b) } // AbsDuration returns the absolute value of a time duration @@ -152,19 +70,3 @@ func MaxTime(a, b time.Time) time.Time { } return b } - -// MaxPacketNumber returns the max packet number -func MaxPacketNumber(a, b protocol.PacketNumber) protocol.PacketNumber { - if a > b { - return a - } - return b -} - -// MinPacketNumber returns the min packet number -func MinPacketNumber(a, b protocol.PacketNumber) protocol.PacketNumber { - if a < b { - return a - } - return b -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/new_connection_id.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/new_connection_id.go deleted file mode 100644 index 694ee7aaf..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/new_connection_id.go +++ /dev/null @@ -1,12 +0,0 @@ -package utils - -import ( - "github.com/lucas-clemente/quic-go/internal/protocol" -) - -// NewConnectionID is a new connection ID -type NewConnectionID struct { - SequenceNumber uint64 - ConnectionID protocol.ConnectionID - StatelessResetToken protocol.StatelessResetToken -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/newconnectionid_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/newconnectionid_linkedlist.go deleted file mode 100644 index d59562e53..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/newconnectionid_linkedlist.go +++ /dev/null @@ -1,217 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package utils - -// Linked list implementation from the Go standard library. - -// NewConnectionIDElement is an element of a linked list. -type NewConnectionIDElement struct { - // Next and previous pointers in the doubly-linked list of elements. - // To simplify the implementation, internally a list l is implemented - // as a ring, such that &l.root is both the next element of the last - // list element (l.Back()) and the previous element of the first list - // element (l.Front()). - next, prev *NewConnectionIDElement - - // The list to which this element belongs. - list *NewConnectionIDList - - // The value stored with this element. - Value NewConnectionID -} - -// Next returns the next list element or nil. -func (e *NewConnectionIDElement) Next() *NewConnectionIDElement { - if p := e.next; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// Prev returns the previous list element or nil. -func (e *NewConnectionIDElement) Prev() *NewConnectionIDElement { - if p := e.prev; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// NewConnectionIDList is a linked list of NewConnectionIDs. -type NewConnectionIDList struct { - root NewConnectionIDElement // sentinel list element, only &root, root.prev, and root.next are used - len int // current list length excluding (this) sentinel element -} - -// Init initializes or clears list l. -func (l *NewConnectionIDList) Init() *NewConnectionIDList { - l.root.next = &l.root - l.root.prev = &l.root - l.len = 0 - return l -} - -// NewNewConnectionIDList returns an initialized list. -func NewNewConnectionIDList() *NewConnectionIDList { return new(NewConnectionIDList).Init() } - -// Len returns the number of elements of list l. -// The complexity is O(1). -func (l *NewConnectionIDList) Len() int { return l.len } - -// Front returns the first element of list l or nil if the list is empty. -func (l *NewConnectionIDList) Front() *NewConnectionIDElement { - if l.len == 0 { - return nil - } - return l.root.next -} - -// Back returns the last element of list l or nil if the list is empty. -func (l *NewConnectionIDList) Back() *NewConnectionIDElement { - if l.len == 0 { - return nil - } - return l.root.prev -} - -// lazyInit lazily initializes a zero List value. -func (l *NewConnectionIDList) lazyInit() { - if l.root.next == nil { - l.Init() - } -} - -// insert inserts e after at, increments l.len, and returns e. -func (l *NewConnectionIDList) insert(e, at *NewConnectionIDElement) *NewConnectionIDElement { - n := at.next - at.next = e - e.prev = at - e.next = n - n.prev = e - e.list = l - l.len++ - return e -} - -// insertValue is a convenience wrapper for insert(&Element{Value: v}, at). -func (l *NewConnectionIDList) insertValue(v NewConnectionID, at *NewConnectionIDElement) *NewConnectionIDElement { - return l.insert(&NewConnectionIDElement{Value: v}, at) -} - -// remove removes e from its list, decrements l.len, and returns e. -func (l *NewConnectionIDList) remove(e *NewConnectionIDElement) *NewConnectionIDElement { - e.prev.next = e.next - e.next.prev = e.prev - e.next = nil // avoid memory leaks - e.prev = nil // avoid memory leaks - e.list = nil - l.len-- - return e -} - -// Remove removes e from l if e is an element of list l. -// It returns the element value e.Value. -// The element must not be nil. -func (l *NewConnectionIDList) Remove(e *NewConnectionIDElement) NewConnectionID { - if e.list == l { - // if e.list == l, l must have been initialized when e was inserted - // in l or l == nil (e is a zero Element) and l.remove will crash - l.remove(e) - } - return e.Value -} - -// PushFront inserts a new element e with value v at the front of list l and returns e. -func (l *NewConnectionIDList) PushFront(v NewConnectionID) *NewConnectionIDElement { - l.lazyInit() - return l.insertValue(v, &l.root) -} - -// PushBack inserts a new element e with value v at the back of list l and returns e. -func (l *NewConnectionIDList) PushBack(v NewConnectionID) *NewConnectionIDElement { - l.lazyInit() - return l.insertValue(v, l.root.prev) -} - -// InsertBefore inserts a new element e with value v immediately before mark and returns e. -// If mark is not an element of l, the list is not modified. -// The mark must not be nil. -func (l *NewConnectionIDList) InsertBefore(v NewConnectionID, mark *NewConnectionIDElement) *NewConnectionIDElement { - if mark.list != l { - return nil - } - // see comment in List.Remove about initialization of l - return l.insertValue(v, mark.prev) -} - -// InsertAfter inserts a new element e with value v immediately after mark and returns e. -// If mark is not an element of l, the list is not modified. -// The mark must not be nil. -func (l *NewConnectionIDList) InsertAfter(v NewConnectionID, mark *NewConnectionIDElement) *NewConnectionIDElement { - if mark.list != l { - return nil - } - // see comment in List.Remove about initialization of l - return l.insertValue(v, mark) -} - -// MoveToFront moves element e to the front of list l. -// If e is not an element of l, the list is not modified. -// The element must not be nil. -func (l *NewConnectionIDList) MoveToFront(e *NewConnectionIDElement) { - if e.list != l || l.root.next == e { - return - } - // see comment in List.Remove about initialization of l - l.insert(l.remove(e), &l.root) -} - -// MoveToBack moves element e to the back of list l. -// If e is not an element of l, the list is not modified. -// The element must not be nil. -func (l *NewConnectionIDList) MoveToBack(e *NewConnectionIDElement) { - if e.list != l || l.root.prev == e { - return - } - // see comment in List.Remove about initialization of l - l.insert(l.remove(e), l.root.prev) -} - -// MoveBefore moves element e to its new position before mark. -// If e or mark is not an element of l, or e == mark, the list is not modified. -// The element and mark must not be nil. -func (l *NewConnectionIDList) MoveBefore(e, mark *NewConnectionIDElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark.prev) -} - -// MoveAfter moves element e to its new position after mark. -// If e or mark is not an element of l, or e == mark, the list is not modified. -// The element and mark must not be nil. -func (l *NewConnectionIDList) MoveAfter(e, mark *NewConnectionIDElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark) -} - -// PushBackList inserts a copy of an other list at the back of list l. -// The lists l and other may be the same. They must not be nil. -func (l *NewConnectionIDList) PushBackList(other *NewConnectionIDList) { - l.lazyInit() - for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { - l.insertValue(e.Value, l.root.prev) - } -} - -// PushFrontList inserts a copy of an other list at the front of list l. -// The lists l and other may be the same. They must not be nil. -func (l *NewConnectionIDList) PushFrontList(other *NewConnectionIDList) { - l.lazyInit() - for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { - l.insertValue(e.Value, &l.root) - } -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/packet_interval.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/packet_interval.go deleted file mode 100644 index 62cc8b9cb..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/packet_interval.go +++ /dev/null @@ -1,9 +0,0 @@ -package utils - -import "github.com/lucas-clemente/quic-go/internal/protocol" - -// PacketInterval is an interval from one PacketNumber to the other -type PacketInterval struct { - Start protocol.PacketNumber - End protocol.PacketNumber -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/packetinterval_linkedlist.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/packetinterval_linkedlist.go deleted file mode 100644 index b461e85a9..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/packetinterval_linkedlist.go +++ /dev/null @@ -1,217 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package utils - -// Linked list implementation from the Go standard library. - -// PacketIntervalElement is an element of a linked list. -type PacketIntervalElement struct { - // Next and previous pointers in the doubly-linked list of elements. - // To simplify the implementation, internally a list l is implemented - // as a ring, such that &l.root is both the next element of the last - // list element (l.Back()) and the previous element of the first list - // element (l.Front()). - next, prev *PacketIntervalElement - - // The list to which this element belongs. - list *PacketIntervalList - - // The value stored with this element. - Value PacketInterval -} - -// Next returns the next list element or nil. -func (e *PacketIntervalElement) Next() *PacketIntervalElement { - if p := e.next; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// Prev returns the previous list element or nil. -func (e *PacketIntervalElement) Prev() *PacketIntervalElement { - if p := e.prev; e.list != nil && p != &e.list.root { - return p - } - return nil -} - -// PacketIntervalList is a linked list of PacketIntervals. -type PacketIntervalList struct { - root PacketIntervalElement // sentinel list element, only &root, root.prev, and root.next are used - len int // current list length excluding (this) sentinel element -} - -// Init initializes or clears list l. -func (l *PacketIntervalList) Init() *PacketIntervalList { - l.root.next = &l.root - l.root.prev = &l.root - l.len = 0 - return l -} - -// NewPacketIntervalList returns an initialized list. -func NewPacketIntervalList() *PacketIntervalList { return new(PacketIntervalList).Init() } - -// Len returns the number of elements of list l. -// The complexity is O(1). -func (l *PacketIntervalList) Len() int { return l.len } - -// Front returns the first element of list l or nil if the list is empty. -func (l *PacketIntervalList) Front() *PacketIntervalElement { - if l.len == 0 { - return nil - } - return l.root.next -} - -// Back returns the last element of list l or nil if the list is empty. -func (l *PacketIntervalList) Back() *PacketIntervalElement { - if l.len == 0 { - return nil - } - return l.root.prev -} - -// lazyInit lazily initializes a zero List value. -func (l *PacketIntervalList) lazyInit() { - if l.root.next == nil { - l.Init() - } -} - -// insert inserts e after at, increments l.len, and returns e. -func (l *PacketIntervalList) insert(e, at *PacketIntervalElement) *PacketIntervalElement { - n := at.next - at.next = e - e.prev = at - e.next = n - n.prev = e - e.list = l - l.len++ - return e -} - -// insertValue is a convenience wrapper for insert(&Element{Value: v}, at). -func (l *PacketIntervalList) insertValue(v PacketInterval, at *PacketIntervalElement) *PacketIntervalElement { - return l.insert(&PacketIntervalElement{Value: v}, at) -} - -// remove removes e from its list, decrements l.len, and returns e. -func (l *PacketIntervalList) remove(e *PacketIntervalElement) *PacketIntervalElement { - e.prev.next = e.next - e.next.prev = e.prev - e.next = nil // avoid memory leaks - e.prev = nil // avoid memory leaks - e.list = nil - l.len-- - return e -} - -// Remove removes e from l if e is an element of list l. -// It returns the element value e.Value. -// The element must not be nil. -func (l *PacketIntervalList) Remove(e *PacketIntervalElement) PacketInterval { - if e.list == l { - // if e.list == l, l must have been initialized when e was inserted - // in l or l == nil (e is a zero Element) and l.remove will crash - l.remove(e) - } - return e.Value -} - -// PushFront inserts a new element e with value v at the front of list l and returns e. -func (l *PacketIntervalList) PushFront(v PacketInterval) *PacketIntervalElement { - l.lazyInit() - return l.insertValue(v, &l.root) -} - -// PushBack inserts a new element e with value v at the back of list l and returns e. -func (l *PacketIntervalList) PushBack(v PacketInterval) *PacketIntervalElement { - l.lazyInit() - return l.insertValue(v, l.root.prev) -} - -// InsertBefore inserts a new element e with value v immediately before mark and returns e. -// If mark is not an element of l, the list is not modified. -// The mark must not be nil. -func (l *PacketIntervalList) InsertBefore(v PacketInterval, mark *PacketIntervalElement) *PacketIntervalElement { - if mark.list != l { - return nil - } - // see comment in List.Remove about initialization of l - return l.insertValue(v, mark.prev) -} - -// InsertAfter inserts a new element e with value v immediately after mark and returns e. -// If mark is not an element of l, the list is not modified. -// The mark must not be nil. -func (l *PacketIntervalList) InsertAfter(v PacketInterval, mark *PacketIntervalElement) *PacketIntervalElement { - if mark.list != l { - return nil - } - // see comment in List.Remove about initialization of l - return l.insertValue(v, mark) -} - -// MoveToFront moves element e to the front of list l. -// If e is not an element of l, the list is not modified. -// The element must not be nil. -func (l *PacketIntervalList) MoveToFront(e *PacketIntervalElement) { - if e.list != l || l.root.next == e { - return - } - // see comment in List.Remove about initialization of l - l.insert(l.remove(e), &l.root) -} - -// MoveToBack moves element e to the back of list l. -// If e is not an element of l, the list is not modified. -// The element must not be nil. -func (l *PacketIntervalList) MoveToBack(e *PacketIntervalElement) { - if e.list != l || l.root.prev == e { - return - } - // see comment in List.Remove about initialization of l - l.insert(l.remove(e), l.root.prev) -} - -// MoveBefore moves element e to its new position before mark. -// If e or mark is not an element of l, or e == mark, the list is not modified. -// The element and mark must not be nil. -func (l *PacketIntervalList) MoveBefore(e, mark *PacketIntervalElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark.prev) -} - -// MoveAfter moves element e to its new position after mark. -// If e or mark is not an element of l, or e == mark, the list is not modified. -// The element and mark must not be nil. -func (l *PacketIntervalList) MoveAfter(e, mark *PacketIntervalElement) { - if e.list != l || e == mark || mark.list != l { - return - } - l.insert(l.remove(e), mark) -} - -// PushBackList inserts a copy of an other list at the back of list l. -// The lists l and other may be the same. They must not be nil. -func (l *PacketIntervalList) PushBackList(other *PacketIntervalList) { - l.lazyInit() - for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() { - l.insertValue(e.Value, l.root.prev) - } -} - -// PushFrontList inserts a copy of an other list at the front of list l. -// The lists l and other may be the same. They must not be nil. -func (l *PacketIntervalList) PushFrontList(other *PacketIntervalList) { - l.lazyInit() - for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() { - l.insertValue(e.Value, &l.root) - } -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/rtt_stats.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/rtt_stats.go index 66642ba8f..1a43ea128 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/rtt_stats.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/utils/rtt_stats.go @@ -55,7 +55,7 @@ func (r *RTTStats) PTO(includeMaxAckDelay bool) time.Duration { if r.SmoothedRTT() == 0 { return 2 * defaultInitialRTT } - pto := r.SmoothedRTT() + MaxDuration(4*r.MeanDeviation(), protocol.TimerGranularity) + pto := r.SmoothedRTT() + Max(4*r.MeanDeviation(), protocol.TimerGranularity) if includeMaxAckDelay { pto += r.MaxAckDelay() } @@ -122,6 +122,6 @@ func (r *RTTStats) OnConnectionMigration() { // is larger. The mean deviation is increased to the most recent deviation if // it's larger. func (r *RTTStats) ExpireSmoothedMetrics() { - r.meanDeviation = MaxDuration(r.meanDeviation, AbsDuration(r.smoothedRTT-r.latestRTT)) - r.smoothedRTT = MaxDuration(r.smoothedRTT, r.latestRTT) + r.meanDeviation = Max(r.meanDeviation, AbsDuration(r.smoothedRTT-r.latestRTT)) + r.smoothedRTT = Max(r.smoothedRTT, r.latestRTT) } diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/utils/streamframe_interval.go b/vendor/github.com/lucas-clemente/quic-go/internal/utils/streamframe_interval.go deleted file mode 100644 index ec16d251b..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/internal/utils/streamframe_interval.go +++ /dev/null @@ -1,9 +0,0 @@ -package utils - -import "github.com/lucas-clemente/quic-go/internal/protocol" - -// ByteInterval is an interval from one ByteCount to the other -type ByteInterval struct { - Start protocol.ByteCount - End protocol.ByteCount -} diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go index f6a31ee0e..a01f40ca4 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/header.go @@ -19,8 +19,7 @@ func ParseConnectionID(data []byte, shortHeaderConnIDLen int) (protocol.Connecti if len(data) == 0 { return nil, io.EOF } - isLongHeader := data[0]&0x80 > 0 - if !isLongHeader { + if !IsLongHeaderPacket(data[0]) { if len(data) < shortHeaderConnIDLen+1 { return nil, io.EOF } @@ -36,12 +35,17 @@ func ParseConnectionID(data []byte, shortHeaderConnIDLen int) (protocol.Connecti return protocol.ConnectionID(data[6 : 6+destConnIDLen]), nil } +// IsLongHeaderPacket says if this is a Long Header packet +func IsLongHeaderPacket(firstByte byte) bool { + return firstByte&0x80 > 0 +} + // IsVersionNegotiationPacket says if this is a version negotiation packet func IsVersionNegotiationPacket(b []byte) bool { if len(b) < 5 { return false } - return b[0]&0x80 > 0 && b[1] == 0 && b[2] == 0 && b[3] == 0 && b[4] == 0 + return IsLongHeaderPacket(b[0]) && b[1] == 0 && b[2] == 0 && b[3] == 0 && b[4] == 0 } // Is0RTTPacket says if this is a 0-RTT packet. @@ -50,7 +54,7 @@ func Is0RTTPacket(b []byte) bool { if len(b) < 5 { return false } - if b[0]&0x80 == 0 { + if !IsLongHeaderPacket(b[0]) { return false } version := protocol.VersionNumber(binary.BigEndian.Uint32(b[1:5])) @@ -129,7 +133,7 @@ func parseHeaderImpl(b *bytes.Reader, shortHeaderConnIDLen int) (*Header, error) h := &Header{ typeByte: typeByte, - IsLongHeader: typeByte&0x80 > 0, + IsLongHeader: IsLongHeaderPacket(typeByte), } if !h.IsLongHeader { diff --git a/vendor/github.com/lucas-clemente/quic-go/internal/wire/transport_parameters.go b/vendor/github.com/lucas-clemente/quic-go/internal/wire/transport_parameters.go index e1f83cd65..65bcfd558 100644 --- a/vendor/github.com/lucas-clemente/quic-go/internal/wire/transport_parameters.go +++ b/vendor/github.com/lucas-clemente/quic-go/internal/wire/transport_parameters.go @@ -285,7 +285,7 @@ func (p *TransportParameters) readNumericTransportParameter( return fmt.Errorf("initial_max_streams_uni too large: %d (maximum %d)", p.MaxUniStreamNum, protocol.MaxStreamCount) } case maxIdleTimeoutParameterID: - p.MaxIdleTimeout = utils.MaxDuration(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond) + p.MaxIdleTimeout = utils.Max(protocol.MinRemoteIdleTimeout, time.Duration(val)*time.Millisecond) case maxUDPPayloadSizeParameterID: if val < 1200 { return fmt.Errorf("invalid value for max_packet_size: %d (minimum 1200)", val) diff --git a/vendor/github.com/lucas-clemente/quic-go/logging/null_tracer.go b/vendor/github.com/lucas-clemente/quic-go/logging/null_tracer.go new file mode 100644 index 000000000..4e0bb60ba --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/logging/null_tracer.go @@ -0,0 +1,52 @@ +package logging + +import ( + "context" + "net" + "time" +) + +// The NullTracer is a Tracer that does nothing. +// It is useful for embedding. +type NullTracer struct{} + +func (n NullTracer) TracerForConnection(context.Context, Perspective, ConnectionID) ConnectionTracer { + return NullConnectionTracer{} +} +func (n NullTracer) SentPacket(net.Addr, *Header, ByteCount, []Frame) {} +func (n NullTracer) DroppedPacket(net.Addr, PacketType, ByteCount, PacketDropReason) {} + +// The NullConnectionTracer is a ConnectionTracer that does nothing. +// It is useful for embedding. +type NullConnectionTracer struct{} + +func (n NullConnectionTracer) StartedConnection(local, remote net.Addr, srcConnID, destConnID ConnectionID) { +} + +func (n NullConnectionTracer) NegotiatedVersion(chosen VersionNumber, clientVersions, serverVersions []VersionNumber) { +} +func (n NullConnectionTracer) ClosedConnection(err error) {} +func (n NullConnectionTracer) SentTransportParameters(*TransportParameters) {} +func (n NullConnectionTracer) ReceivedTransportParameters(*TransportParameters) {} +func (n NullConnectionTracer) RestoredTransportParameters(*TransportParameters) {} +func (n NullConnectionTracer) SentPacket(*ExtendedHeader, ByteCount, *AckFrame, []Frame) {} +func (n NullConnectionTracer) ReceivedVersionNegotiationPacket(*Header, []VersionNumber) {} +func (n NullConnectionTracer) ReceivedRetry(*Header) {} +func (n NullConnectionTracer) ReceivedPacket(hdr *ExtendedHeader, size ByteCount, frames []Frame) {} +func (n NullConnectionTracer) BufferedPacket(PacketType) {} +func (n NullConnectionTracer) DroppedPacket(PacketType, ByteCount, PacketDropReason) {} +func (n NullConnectionTracer) UpdatedMetrics(rttStats *RTTStats, cwnd, bytesInFlight ByteCount, packetsInFlight int) { +} +func (n NullConnectionTracer) AcknowledgedPacket(EncryptionLevel, PacketNumber) {} +func (n NullConnectionTracer) LostPacket(EncryptionLevel, PacketNumber, PacketLossReason) {} +func (n NullConnectionTracer) UpdatedCongestionState(CongestionState) {} +func (n NullConnectionTracer) UpdatedPTOCount(uint32) {} +func (n NullConnectionTracer) UpdatedKeyFromTLS(EncryptionLevel, Perspective) {} +func (n NullConnectionTracer) UpdatedKey(keyPhase KeyPhase, remote bool) {} +func (n NullConnectionTracer) DroppedEncryptionLevel(EncryptionLevel) {} +func (n NullConnectionTracer) DroppedKey(KeyPhase) {} +func (n NullConnectionTracer) SetLossTimer(TimerType, EncryptionLevel, time.Time) {} +func (n NullConnectionTracer) LossTimerExpired(timerType TimerType, level EncryptionLevel) {} +func (n NullConnectionTracer) LossTimerCanceled() {} +func (n NullConnectionTracer) Close() {} +func (n NullConnectionTracer) Debug(name, msg string) {} diff --git a/vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go b/vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go index 2d55a95ef..0caa49075 100644 --- a/vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go +++ b/vendor/github.com/lucas-clemente/quic-go/packet_handler_map.go @@ -22,33 +22,6 @@ import ( "github.com/lucas-clemente/quic-go/logging" ) -type zeroRTTQueue struct { - queue []*receivedPacket - retireTimer *time.Timer -} - -var _ packetHandler = &zeroRTTQueue{} - -func (h *zeroRTTQueue) handlePacket(p *receivedPacket) { - if len(h.queue) < protocol.Max0RTTQueueLen { - h.queue = append(h.queue, p) - } -} -func (h *zeroRTTQueue) shutdown() {} -func (h *zeroRTTQueue) destroy(error) {} -func (h *zeroRTTQueue) getPerspective() protocol.Perspective { return protocol.PerspectiveClient } -func (h *zeroRTTQueue) EnqueueAll(sess packetHandler) { - for _, p := range h.queue { - sess.handlePacket(p) - } -} - -func (h *zeroRTTQueue) Clear() { - for _, p := range h.queue { - p.buffer.Release() - } -} - // rawConn is a connection that allow reading of a receivedPacket. type rawConn interface { ReadPacket() (*receivedPacket, error) @@ -57,9 +30,10 @@ type rawConn interface { io.Closer } -type packetHandlerMapEntry struct { - packetHandler packetHandler - is0RTTQueue bool +type closePacket struct { + payload []byte + addr net.Addr + info *packetInfo } // The packetHandlerMap stores packetHandlers, identified by connection ID. @@ -72,7 +46,9 @@ type packetHandlerMap struct { conn rawConn connIDLen int - handlers map[string] /* string(ConnectionID)*/ packetHandlerMapEntry + closeQueue chan closePacket + + handlers map[string] /* string(ConnectionID)*/ packetHandler resetTokens map[protocol.StatelessResetToken] /* stateless reset token */ packetHandler server unknownPacketHandler numZeroRTTEntries int @@ -151,16 +127,18 @@ func newPacketHandlerMap( conn: conn, connIDLen: connIDLen, listening: make(chan struct{}), - handlers: make(map[string]packetHandlerMapEntry), + handlers: make(map[string]packetHandler), resetTokens: make(map[protocol.StatelessResetToken]packetHandler), deleteRetiredConnsAfter: protocol.RetiredConnectionIDDeleteTimeout, zeroRTTQueueDuration: protocol.Max0RTTQueueingDuration, + closeQueue: make(chan closePacket, 4), statelessResetEnabled: len(statelessResetKey) > 0, statelessResetHasher: hmac.New(sha256.New, statelessResetKey), tracer: tracer, logger: logger, } go m.listen() + go m.runCloseQueue() if logger.Debug() { go m.logUsage() @@ -202,7 +180,7 @@ func (h *packetHandlerMap) Add(id protocol.ConnectionID, handler packetHandler) h.logger.Debugf("Not adding connection ID %s, as it already exists.", id) return false } - h.handlers[string(id)] = packetHandlerMapEntry{packetHandler: handler} + h.handlers[string(id)] = handler h.logger.Debugf("Adding connection ID %s.", id) return true } @@ -212,24 +190,24 @@ func (h *packetHandlerMap) AddWithConnID(clientDestConnID, newConnID protocol.Co defer h.mutex.Unlock() var q *zeroRTTQueue - if entry, ok := h.handlers[string(clientDestConnID)]; ok { - if !entry.is0RTTQueue { + if handler, ok := h.handlers[string(clientDestConnID)]; ok { + q, ok = handler.(*zeroRTTQueue) + if !ok { h.logger.Debugf("Not adding connection ID %s for a new connection, as it already exists.", clientDestConnID) return false } - q = entry.packetHandler.(*zeroRTTQueue) q.retireTimer.Stop() h.numZeroRTTEntries-- if h.numZeroRTTEntries < 0 { panic("number of 0-RTT queues < 0") } } - sess := fn() + conn := fn() if q != nil { - q.EnqueueAll(sess) + q.EnqueueAll(conn) } - h.handlers[string(clientDestConnID)] = packetHandlerMapEntry{packetHandler: sess} - h.handlers[string(newConnID)] = packetHandlerMapEntry{packetHandler: sess} + h.handlers[string(clientDestConnID)] = conn + h.handlers[string(newConnID)] = conn h.logger.Debugf("Adding connection IDs %s and %s for a new connection.", clientDestConnID, newConnID) return true } @@ -251,21 +229,58 @@ func (h *packetHandlerMap) Retire(id protocol.ConnectionID) { }) } -func (h *packetHandlerMap) ReplaceWithClosed(id protocol.ConnectionID, handler packetHandler) { +// ReplaceWithClosed is called when a connection is closed. +// Depending on which side closed the connection, we need to: +// * remote close: absorb delayed packets +// * local close: retransmit the CONNECTION_CLOSE packet, in case it was lost +func (h *packetHandlerMap) ReplaceWithClosed(ids []protocol.ConnectionID, pers protocol.Perspective, connClosePacket []byte) { + var handler packetHandler + if connClosePacket != nil { + handler = newClosedLocalConn( + func(addr net.Addr, info *packetInfo) { + select { + case h.closeQueue <- closePacket{payload: connClosePacket, addr: addr, info: info}: + default: + // Oops, we're backlogged. + // Just drop the packet, sending CONNECTION_CLOSE copies is best effort anyway. + } + }, + pers, + h.logger, + ) + } else { + handler = newClosedRemoteConn(pers) + } + h.mutex.Lock() - h.handlers[string(id)] = packetHandlerMapEntry{packetHandler: handler} + for _, id := range ids { + h.handlers[string(id)] = handler + } h.mutex.Unlock() - h.logger.Debugf("Replacing connection for connection ID %s with a closed connection.", id) + h.logger.Debugf("Replacing connection for connection IDs %s with a closed connection.", ids) time.AfterFunc(h.deleteRetiredConnsAfter, func() { h.mutex.Lock() handler.shutdown() - delete(h.handlers, string(id)) + for _, id := range ids { + delete(h.handlers, string(id)) + } h.mutex.Unlock() - h.logger.Debugf("Removing connection ID %s for a closed connection after it has been retired.", id) + h.logger.Debugf("Removing connection IDs %s for a closed connection after it has been retired.", ids) }) } +func (h *packetHandlerMap) runCloseQueue() { + for { + select { + case <-h.listening: + return + case p := <-h.closeQueue: + h.conn.WritePacket(p.payload, p.addr, p.info.OOB()) + } + } +} + func (h *packetHandlerMap) AddResetToken(token protocol.StatelessResetToken, handler packetHandler) { h.mutex.Lock() h.resetTokens[token] = handler @@ -292,14 +307,14 @@ func (h *packetHandlerMap) CloseServer() { } h.server = nil var wg sync.WaitGroup - for _, entry := range h.handlers { - if entry.packetHandler.getPerspective() == protocol.PerspectiveServer { + for _, handler := range h.handlers { + if handler.getPerspective() == protocol.PerspectiveServer { wg.Add(1) go func(handler packetHandler) { // blocks until the CONNECTION_CLOSE has been sent and the run-loop has stopped handler.shutdown() wg.Done() - }(entry.packetHandler) + }(handler) } } h.mutex.Unlock() @@ -324,12 +339,12 @@ func (h *packetHandlerMap) close(e error) error { } var wg sync.WaitGroup - for _, entry := range h.handlers { + for _, handler := range h.handlers { wg.Add(1) go func(handler packetHandler) { handler.destroy(e) wg.Done() - }(entry.packetHandler) + }(handler) } if h.server != nil { @@ -379,18 +394,18 @@ func (h *packetHandlerMap) handlePacket(p *receivedPacket) { return } - if entry, ok := h.handlers[string(connID)]; ok { - if entry.is0RTTQueue { // only enqueue 0-RTT packets in the 0-RTT queue + if handler, ok := h.handlers[string(connID)]; ok { + if ha, ok := handler.(*zeroRTTQueue); ok { // only enqueue 0-RTT packets in the 0-RTT queue if wire.Is0RTTPacket(p.data) { - entry.packetHandler.handlePacket(p) + ha.handlePacket(p) return } } else { // existing connection - entry.packetHandler.handlePacket(p) + handler.handlePacket(p) return } } - if p.data[0]&0x80 == 0 { + if !wire.IsLongHeaderPacket(p.data[0]) { go h.maybeSendStatelessReset(p, connID) return } @@ -404,24 +419,23 @@ func (h *packetHandlerMap) handlePacket(p *receivedPacket) { } h.numZeroRTTEntries++ queue := &zeroRTTQueue{queue: make([]*receivedPacket, 0, 8)} - h.handlers[string(connID)] = packetHandlerMapEntry{ - packetHandler: queue, - is0RTTQueue: true, - } + h.handlers[string(connID)] = queue queue.retireTimer = time.AfterFunc(h.zeroRTTQueueDuration, func() { h.mutex.Lock() defer h.mutex.Unlock() // The entry might have been replaced by an actual connection. // Only delete it if it's still a 0-RTT queue. - if entry, ok := h.handlers[string(connID)]; ok && entry.is0RTTQueue { - delete(h.handlers, string(connID)) - h.numZeroRTTEntries-- - if h.numZeroRTTEntries < 0 { - panic("number of 0-RTT queues < 0") - } - entry.packetHandler.(*zeroRTTQueue).Clear() - if h.logger.Debug() { - h.logger.Debugf("Removing 0-RTT queue for %s.", connID) + if handler, ok := h.handlers[string(connID)]; ok { + if q, ok := handler.(*zeroRTTQueue); ok { + delete(h.handlers, string(connID)) + h.numZeroRTTEntries-- + if h.numZeroRTTEntries < 0 { + panic("number of 0-RTT queues < 0") + } + q.Clear() + if h.logger.Debug() { + h.logger.Debugf("Removing 0-RTT queue for %s.", connID) + } } } }) @@ -433,7 +447,7 @@ func (h *packetHandlerMap) handlePacket(p *receivedPacket) { func (h *packetHandlerMap) maybeHandleStatelessReset(data []byte) bool { // stateless resets are always short header packets - if data[0]&0x80 != 0 { + if wire.IsLongHeaderPacket(data[0]) { return false } if len(data) < 17 /* type byte + 16 bytes for the reset token */ { diff --git a/vendor/github.com/lucas-clemente/quic-go/packet_packer.go b/vendor/github.com/lucas-clemente/quic-go/packet_packer.go index 1d037ab28..aec485f00 100644 --- a/vendor/github.com/lucas-clemente/quic-go/packet_packer.go +++ b/vendor/github.com/lucas-clemente/quic-go/packet_packer.go @@ -889,6 +889,6 @@ func (p *packetPacker) SetMaxPacketSize(s protocol.ByteCount) { // we need to reduce the size of packets we send. func (p *packetPacker) HandleTransportParameters(params *wire.TransportParameters) { if params.MaxUDPPayloadSize != 0 { - p.maxPacketSize = utils.MinByteCount(p.maxPacketSize, params.MaxUDPPayloadSize) + p.maxPacketSize = utils.Min(p.maxPacketSize, params.MaxUDPPayloadSize) } } diff --git a/vendor/github.com/lucas-clemente/quic-go/send_stream.go b/vendor/github.com/lucas-clemente/quic-go/send_stream.go index b23df00b3..3daf67813 100644 --- a/vendor/github.com/lucas-clemente/quic-go/send_stream.go +++ b/vendor/github.com/lucas-clemente/quic-go/send_stream.go @@ -277,7 +277,7 @@ func (s *sendStream) popNewStreamFrame(maxBytes, sendWindow protocol.ByteCount) nextFrame := s.nextFrame s.nextFrame = nil - maxDataLen := utils.MinByteCount(sendWindow, nextFrame.MaxDataLen(maxBytes, s.version)) + maxDataLen := utils.Min(sendWindow, nextFrame.MaxDataLen(maxBytes, s.version)) if nextFrame.DataLen() > maxDataLen { s.nextFrame = wire.GetStreamFrame() s.nextFrame.StreamID = s.streamID @@ -312,7 +312,7 @@ func (s *sendStream) popNewStreamFrameWithoutBuffer(f *wire.StreamFrame, maxByte if maxDataLen == 0 { // a STREAM frame must have at least one byte of data return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting } - s.getDataForWriting(f, utils.MinByteCount(maxDataLen, sendWindow)) + s.getDataForWriting(f, utils.Min(maxDataLen, sendWindow)) return s.dataForWriting != nil || s.nextFrame != nil || s.finishedWriting } diff --git a/vendor/github.com/lucas-clemente/quic-go/server.go b/vendor/github.com/lucas-clemente/quic-go/server.go index 0e6429705..ac68681c7 100644 --- a/vendor/github.com/lucas-clemente/quic-go/server.go +++ b/vendor/github.com/lucas-clemente/quic-go/server.go @@ -89,6 +89,7 @@ type baseServer struct { *tls.Config, *handshake.TokenGenerator, bool, /* enable 0-RTT */ + bool, /* client address validated by an address validation token */ logging.ConnectionTracer, uint64, utils.Logger, @@ -190,7 +191,7 @@ func listen(conn net.PacketConn, tlsConf *tls.Config, config *Config, acceptEarl } } - connHandler, err := getMultiplexer().AddConn(conn, config.ConnectionIDLength, config.StatelessResetKey, config.Tracer) + connHandler, err := getMultiplexer().AddConn(conn, config.ConnectionIDGenerator.ConnectionIDLen(), config.StatelessResetKey, config.Tracer) if err != nil { return nil, err } @@ -241,26 +242,6 @@ func (s *baseServer) run() { } } -var defaultAcceptToken = func(clientAddr net.Addr, token *Token) bool { - if token == nil { - return false - } - validity := protocol.TokenValidity - if token.IsRetryToken { - validity = protocol.RetryTokenValidity - } - if time.Now().After(token.SentTime.Add(validity)) { - return false - } - var sourceAddr string - if udpAddr, ok := clientAddr.(*net.UDPAddr); ok { - sourceAddr = udpAddr.IP.String() - } else { - sourceAddr = clientAddr.String() - } - return sourceAddr == token.RemoteAddr -} - // Accept returns connections that already completed the handshake. // It is only valid if acceptEarlyConns is false. func (s *baseServer) Accept(ctx context.Context) (Connection, error) { @@ -341,7 +322,7 @@ func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* is the buffer s } // If we're creating a new connection, the packet will be passed to the connection. // The header will then be parsed again. - hdr, _, _, err := wire.ParsePacket(p.data, s.config.ConnectionIDLength) + hdr, _, _, err := wire.ParsePacket(p.data, s.config.ConnectionIDGenerator.ConnectionIDLen()) if err != nil && err != wire.ErrUnsupportedVersion { if s.config.Tracer != nil { s.config.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError) @@ -395,6 +376,26 @@ func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* is the buffer s return true } +// validateToken returns false if: +// - address is invalid +// - token is expired +// - token is null +func (s *baseServer) validateToken(token *handshake.Token, addr net.Addr) bool { + if token == nil { + return false + } + if !token.ValidateRemoteAddr(addr) { + return false + } + if !token.IsRetryToken && time.Since(token.SentTime) > s.config.MaxTokenAge { + return false + } + if token.IsRetryToken && time.Since(token.SentTime) > s.config.MaxRetryTokenAge { + return false + } + return true +} + func (s *baseServer) handleInitialImpl(p *receivedPacket, hdr *wire.Header) error { if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial { p.buffer.Release() @@ -405,33 +406,45 @@ func (s *baseServer) handleInitialImpl(p *receivedPacket, hdr *wire.Header) erro } var ( - token *Token + token *handshake.Token retrySrcConnID *protocol.ConnectionID ) origDestConnID := hdr.DestConnectionID if len(hdr.Token) > 0 { - c, err := s.tokenGenerator.DecodeToken(hdr.Token) + tok, err := s.tokenGenerator.DecodeToken(hdr.Token) if err == nil { - token = &Token{ - IsRetryToken: c.IsRetryToken, - RemoteAddr: c.RemoteAddr, - SentTime: c.SentTime, - } - if token.IsRetryToken { - origDestConnID = c.OriginalDestConnectionID - retrySrcConnID = &c.RetrySrcConnectionID + if tok.IsRetryToken { + origDestConnID = tok.OriginalDestConnectionID + retrySrcConnID = &tok.RetrySrcConnectionID } + token = tok } } - if !s.config.AcceptToken(p.remoteAddr, token) { - go func() { - defer p.buffer.Release() - if token != nil && token.IsRetryToken { + + clientAddrIsValid := s.validateToken(token, p.remoteAddr) + + if token != nil && !clientAddrIsValid { + // For invalid and expired non-retry tokens, we don't send an INVALID_TOKEN error. + // We just ignore them, and act as if there was no token on this packet at all. + // This also means we might send a Retry later. + if !token.IsRetryToken { + token = nil + } else { + // For Retry tokens, we send an INVALID_ERROR if + // * the token is too old, or + // * the token is invalid, in case of a retry token. + go func() { + defer p.buffer.Release() if err := s.maybeSendInvalidToken(p, hdr); err != nil { s.logger.Debugf("Error sending INVALID_TOKEN error: %s", err) } - return - } + }() + return nil + } + } + if token == nil && s.config.RequireAddressValidation(p.remoteAddr) { + go func() { + defer p.buffer.Release() if err := s.sendRetry(p.remoteAddr, hdr, p.info); err != nil { s.logger.Debugf("Error sending Retry: %s", err) } @@ -450,11 +463,11 @@ func (s *baseServer) handleInitialImpl(p *receivedPacket, hdr *wire.Header) erro return nil } - connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) + connID, err := s.config.ConnectionIDGenerator.GenerateConnectionID() if err != nil { return err } - s.logger.Debugf("Changing connection ID to %s.", connID) + s.logger.Debugf("Changing connection ID to %s.", protocol.ConnectionID(connID)) var conn quicConn tracingID := nextConnTracingID() if added := s.connHandler.AddWithConnID(hdr.DestConnectionID, connID, func() packetHandler { @@ -484,6 +497,7 @@ func (s *baseServer) handleInitialImpl(p *receivedPacket, hdr *wire.Header) erro s.tlsConf, s.tokenGenerator, s.acceptEarlyConns, + clientAddrIsValid, tracer, tracingID, s.logger, @@ -535,7 +549,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info *pack // Log the Initial packet now. // If no Retry is sent, the packet will be logged by the connection. (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) - srcConnID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength) + srcConnID, err := s.config.ConnectionIDGenerator.GenerateConnectionID() if err != nil { return err } @@ -551,7 +565,7 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header, info *pack replyHdr.DestConnectionID = hdr.SrcConnectionID replyHdr.Token = token if s.logger.Debug() { - s.logger.Debugf("Changing connection ID to %s.", srcConnID) + s.logger.Debugf("Changing connection ID to %s.", protocol.ConnectionID(srcConnID)) s.logger.Debugf("-> Sending Retry") replyHdr.Log(s.logger) } diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map.go b/vendor/github.com/lucas-clemente/quic-go/streams_map.go index 79c1ee91a..e9f0c2e10 100644 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map.go +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map.go @@ -55,10 +55,10 @@ type streamsMap struct { newFlowController func(protocol.StreamID) flowcontrol.StreamFlowController mutex sync.Mutex - outgoingBidiStreams *outgoingBidiStreamsMap - outgoingUniStreams *outgoingUniStreamsMap - incomingBidiStreams *incomingBidiStreamsMap - incomingUniStreams *incomingUniStreamsMap + outgoingBidiStreams *outgoingStreamsMap[streamI] + outgoingUniStreams *outgoingStreamsMap[sendStreamI] + incomingBidiStreams *incomingStreamsMap[streamI] + incomingUniStreams *incomingStreamsMap[receiveStreamI] reset bool } @@ -85,14 +85,16 @@ func newStreamsMap( } func (m *streamsMap) initMaps() { - m.outgoingBidiStreams = newOutgoingBidiStreamsMap( + m.outgoingBidiStreams = newOutgoingStreamsMap( + protocol.StreamTypeBidi, func(num protocol.StreamNum) streamI { id := num.StreamID(protocol.StreamTypeBidi, m.perspective) return newStream(id, m.sender, m.newFlowController(id), m.version) }, m.sender.queueControlFrame, ) - m.incomingBidiStreams = newIncomingBidiStreamsMap( + m.incomingBidiStreams = newIncomingStreamsMap( + protocol.StreamTypeBidi, func(num protocol.StreamNum) streamI { id := num.StreamID(protocol.StreamTypeBidi, m.perspective.Opposite()) return newStream(id, m.sender, m.newFlowController(id), m.version) @@ -100,14 +102,16 @@ func (m *streamsMap) initMaps() { m.maxIncomingBidiStreams, m.sender.queueControlFrame, ) - m.outgoingUniStreams = newOutgoingUniStreamsMap( + m.outgoingUniStreams = newOutgoingStreamsMap( + protocol.StreamTypeUni, func(num protocol.StreamNum) sendStreamI { id := num.StreamID(protocol.StreamTypeUni, m.perspective) return newSendStream(id, m.sender, m.newFlowController(id), m.version) }, m.sender.queueControlFrame, ) - m.incomingUniStreams = newIncomingUniStreamsMap( + m.incomingUniStreams = newIncomingStreamsMap( + protocol.StreamTypeUni, func(num protocol.StreamNum) receiveStreamI { id := num.StreamID(protocol.StreamTypeUni, m.perspective.Opposite()) return newReceiveStream(id, m.sender, m.newFlowController(id), m.version) diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_generic_helper.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_generic_helper.go deleted file mode 100644 index 26b562331..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map_generic_helper.go +++ /dev/null @@ -1,18 +0,0 @@ -package quic - -import ( - "github.com/cheekybits/genny/generic" - - "github.com/lucas-clemente/quic-go/internal/protocol" -) - -// In the auto-generated streams maps, we need to be able to close the streams. -// Therefore, extend the generic.Type with the stream close method. -// This definition must be in a file that Genny doesn't process. -type item interface { - generic.Type - updateSendWindow(protocol.ByteCount) - closeForShutdown(error) -} - -const streamTypeGeneric protocol.StreamType = protocol.StreamTypeUni diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming.go similarity index 78% rename from vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go rename to vendor/github.com/lucas-clemente/quic-go/streams_map_incoming.go index 5bddec00b..6fe0c61b5 100644 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_uni.go +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming.go @@ -1,7 +1,3 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - package quic import ( @@ -12,38 +8,45 @@ import ( "github.com/lucas-clemente/quic-go/internal/wire" ) +type incomingStream interface { + closeForShutdown(error) +} + // When a stream is deleted before it was accepted, we can't delete it from the map immediately. // We need to wait until the application accepts it, and delete it then. -type receiveStreamIEntry struct { - stream receiveStreamI +type incomingStreamEntry[T incomingStream] struct { + stream T shouldDelete bool } -type incomingUniStreamsMap struct { +type incomingStreamsMap[T incomingStream] struct { mutex sync.RWMutex newStreamChan chan struct{} - streams map[protocol.StreamNum]receiveStreamIEntry + streamType protocol.StreamType + streams map[protocol.StreamNum]incomingStreamEntry[T] nextStreamToAccept protocol.StreamNum // the next stream that will be returned by AcceptStream() nextStreamToOpen protocol.StreamNum // the highest stream that the peer opened maxStream protocol.StreamNum // the highest stream that the peer is allowed to open maxNumStreams uint64 // maximum number of streams - newStream func(protocol.StreamNum) receiveStreamI + newStream func(protocol.StreamNum) T queueMaxStreamID func(*wire.MaxStreamsFrame) closeErr error } -func newIncomingUniStreamsMap( - newStream func(protocol.StreamNum) receiveStreamI, +func newIncomingStreamsMap[T incomingStream]( + streamType protocol.StreamType, + newStream func(protocol.StreamNum) T, maxStreams uint64, queueControlFrame func(wire.Frame), -) *incomingUniStreamsMap { - return &incomingUniStreamsMap{ +) *incomingStreamsMap[T] { + return &incomingStreamsMap[T]{ newStreamChan: make(chan struct{}, 1), - streams: make(map[protocol.StreamNum]receiveStreamIEntry), + streamType: streamType, + streams: make(map[protocol.StreamNum]incomingStreamEntry[T]), maxStream: protocol.StreamNum(maxStreams), maxNumStreams: maxStreams, newStream: newStream, @@ -53,7 +56,7 @@ func newIncomingUniStreamsMap( } } -func (m *incomingUniStreamsMap) AcceptStream(ctx context.Context) (receiveStreamI, error) { +func (m *incomingStreamsMap[T]) AcceptStream(ctx context.Context) (T, error) { // drain the newStreamChan, so we don't check the map twice if the stream doesn't exist select { case <-m.newStreamChan: @@ -63,12 +66,12 @@ func (m *incomingUniStreamsMap) AcceptStream(ctx context.Context) (receiveStream m.mutex.Lock() var num protocol.StreamNum - var entry receiveStreamIEntry + var entry incomingStreamEntry[T] for { num = m.nextStreamToAccept if m.closeErr != nil { m.mutex.Unlock() - return nil, m.closeErr + return *new(T), m.closeErr } var ok bool entry, ok = m.streams[num] @@ -78,7 +81,7 @@ func (m *incomingUniStreamsMap) AcceptStream(ctx context.Context) (receiveStream m.mutex.Unlock() select { case <-ctx.Done(): - return nil, ctx.Err() + return *new(T), ctx.Err() case <-m.newStreamChan: } m.mutex.Lock() @@ -88,18 +91,18 @@ func (m *incomingUniStreamsMap) AcceptStream(ctx context.Context) (receiveStream if entry.shouldDelete { if err := m.deleteStream(num); err != nil { m.mutex.Unlock() - return nil, err + return *new(T), err } } m.mutex.Unlock() return entry.stream, nil } -func (m *incomingUniStreamsMap) GetOrOpenStream(num protocol.StreamNum) (receiveStreamI, error) { +func (m *incomingStreamsMap[T]) GetOrOpenStream(num protocol.StreamNum) (T, error) { m.mutex.RLock() if num > m.maxStream { m.mutex.RUnlock() - return nil, streamError{ + return *new(T), streamError{ message: "peer tried to open stream %d (current limit: %d)", nums: []protocol.StreamNum{num, m.maxStream}, } @@ -108,7 +111,7 @@ func (m *incomingUniStreamsMap) GetOrOpenStream(num protocol.StreamNum) (receive // * this stream exists in the map, and we can return it, or // * this stream was already closed, then we can return the nil if num < m.nextStreamToOpen { - var s receiveStreamI + var s T // If the stream was already queued for deletion, and is just waiting to be accepted, don't return it. if entry, ok := m.streams[num]; ok && !entry.shouldDelete { s = entry.stream @@ -123,7 +126,7 @@ func (m *incomingUniStreamsMap) GetOrOpenStream(num protocol.StreamNum) (receive // * maxStream can only increase, so if the id was valid before, it definitely is valid now // * highestStream is only modified by this function for newNum := m.nextStreamToOpen; newNum <= num; newNum++ { - m.streams[newNum] = receiveStreamIEntry{stream: m.newStream(newNum)} + m.streams[newNum] = incomingStreamEntry[T]{stream: m.newStream(newNum)} select { case m.newStreamChan <- struct{}{}: default: @@ -135,14 +138,14 @@ func (m *incomingUniStreamsMap) GetOrOpenStream(num protocol.StreamNum) (receive return entry.stream, nil } -func (m *incomingUniStreamsMap) DeleteStream(num protocol.StreamNum) error { +func (m *incomingStreamsMap[T]) DeleteStream(num protocol.StreamNum) error { m.mutex.Lock() defer m.mutex.Unlock() return m.deleteStream(num) } -func (m *incomingUniStreamsMap) deleteStream(num protocol.StreamNum) error { +func (m *incomingStreamsMap[T]) deleteStream(num protocol.StreamNum) error { if _, ok := m.streams[num]; !ok { return streamError{ message: "tried to delete unknown incoming stream %d", @@ -173,7 +176,7 @@ func (m *incomingUniStreamsMap) deleteStream(num protocol.StreamNum) error { if maxStream <= protocol.MaxStreamCount { m.maxStream = maxStream m.queueMaxStreamID(&wire.MaxStreamsFrame{ - Type: protocol.StreamTypeUni, + Type: m.streamType, MaxStreamNum: m.maxStream, }) } @@ -181,7 +184,7 @@ func (m *incomingUniStreamsMap) deleteStream(num protocol.StreamNum) error { return nil } -func (m *incomingUniStreamsMap) CloseWithError(err error) { +func (m *incomingStreamsMap[T]) CloseWithError(err error) { m.mutex.Lock() m.closeErr = err for _, entry := range m.streams { diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go deleted file mode 100644 index 46c8c73a0..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_bidi.go +++ /dev/null @@ -1,192 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package quic - -import ( - "context" - "sync" - - "github.com/lucas-clemente/quic-go/internal/protocol" - "github.com/lucas-clemente/quic-go/internal/wire" -) - -// When a stream is deleted before it was accepted, we can't delete it from the map immediately. -// We need to wait until the application accepts it, and delete it then. -type streamIEntry struct { - stream streamI - shouldDelete bool -} - -type incomingBidiStreamsMap struct { - mutex sync.RWMutex - newStreamChan chan struct{} - - streams map[protocol.StreamNum]streamIEntry - - nextStreamToAccept protocol.StreamNum // the next stream that will be returned by AcceptStream() - nextStreamToOpen protocol.StreamNum // the highest stream that the peer opened - maxStream protocol.StreamNum // the highest stream that the peer is allowed to open - maxNumStreams uint64 // maximum number of streams - - newStream func(protocol.StreamNum) streamI - queueMaxStreamID func(*wire.MaxStreamsFrame) - - closeErr error -} - -func newIncomingBidiStreamsMap( - newStream func(protocol.StreamNum) streamI, - maxStreams uint64, - queueControlFrame func(wire.Frame), -) *incomingBidiStreamsMap { - return &incomingBidiStreamsMap{ - newStreamChan: make(chan struct{}, 1), - streams: make(map[protocol.StreamNum]streamIEntry), - maxStream: protocol.StreamNum(maxStreams), - maxNumStreams: maxStreams, - newStream: newStream, - nextStreamToOpen: 1, - nextStreamToAccept: 1, - queueMaxStreamID: func(f *wire.MaxStreamsFrame) { queueControlFrame(f) }, - } -} - -func (m *incomingBidiStreamsMap) AcceptStream(ctx context.Context) (streamI, error) { - // drain the newStreamChan, so we don't check the map twice if the stream doesn't exist - select { - case <-m.newStreamChan: - default: - } - - m.mutex.Lock() - - var num protocol.StreamNum - var entry streamIEntry - for { - num = m.nextStreamToAccept - if m.closeErr != nil { - m.mutex.Unlock() - return nil, m.closeErr - } - var ok bool - entry, ok = m.streams[num] - if ok { - break - } - m.mutex.Unlock() - select { - case <-ctx.Done(): - return nil, ctx.Err() - case <-m.newStreamChan: - } - m.mutex.Lock() - } - m.nextStreamToAccept++ - // If this stream was completed before being accepted, we can delete it now. - if entry.shouldDelete { - if err := m.deleteStream(num); err != nil { - m.mutex.Unlock() - return nil, err - } - } - m.mutex.Unlock() - return entry.stream, nil -} - -func (m *incomingBidiStreamsMap) GetOrOpenStream(num protocol.StreamNum) (streamI, error) { - m.mutex.RLock() - if num > m.maxStream { - m.mutex.RUnlock() - return nil, streamError{ - message: "peer tried to open stream %d (current limit: %d)", - nums: []protocol.StreamNum{num, m.maxStream}, - } - } - // if the num is smaller than the highest we accepted - // * this stream exists in the map, and we can return it, or - // * this stream was already closed, then we can return the nil - if num < m.nextStreamToOpen { - var s streamI - // If the stream was already queued for deletion, and is just waiting to be accepted, don't return it. - if entry, ok := m.streams[num]; ok && !entry.shouldDelete { - s = entry.stream - } - m.mutex.RUnlock() - return s, nil - } - m.mutex.RUnlock() - - m.mutex.Lock() - // no need to check the two error conditions from above again - // * maxStream can only increase, so if the id was valid before, it definitely is valid now - // * highestStream is only modified by this function - for newNum := m.nextStreamToOpen; newNum <= num; newNum++ { - m.streams[newNum] = streamIEntry{stream: m.newStream(newNum)} - select { - case m.newStreamChan <- struct{}{}: - default: - } - } - m.nextStreamToOpen = num + 1 - entry := m.streams[num] - m.mutex.Unlock() - return entry.stream, nil -} - -func (m *incomingBidiStreamsMap) DeleteStream(num protocol.StreamNum) error { - m.mutex.Lock() - defer m.mutex.Unlock() - - return m.deleteStream(num) -} - -func (m *incomingBidiStreamsMap) deleteStream(num protocol.StreamNum) error { - if _, ok := m.streams[num]; !ok { - return streamError{ - message: "tried to delete unknown incoming stream %d", - nums: []protocol.StreamNum{num}, - } - } - - // Don't delete this stream yet, if it was not yet accepted. - // Just save it to streamsToDelete map, to make sure it is deleted as soon as it gets accepted. - if num >= m.nextStreamToAccept { - entry, ok := m.streams[num] - if ok && entry.shouldDelete { - return streamError{ - message: "tried to delete incoming stream %d multiple times", - nums: []protocol.StreamNum{num}, - } - } - entry.shouldDelete = true - m.streams[num] = entry // can't assign to struct in map, so we need to reassign - return nil - } - - delete(m.streams, num) - // queue a MAX_STREAM_ID frame, giving the peer the option to open a new stream - if m.maxNumStreams > uint64(len(m.streams)) { - maxStream := m.nextStreamToOpen + protocol.StreamNum(m.maxNumStreams-uint64(len(m.streams))) - 1 - // Never send a value larger than protocol.MaxStreamCount. - if maxStream <= protocol.MaxStreamCount { - m.maxStream = maxStream - m.queueMaxStreamID(&wire.MaxStreamsFrame{ - Type: protocol.StreamTypeBidi, - MaxStreamNum: m.maxStream, - }) - } - } - return nil -} - -func (m *incomingBidiStreamsMap) CloseWithError(err error) { - m.mutex.Lock() - m.closeErr = err - for _, entry := range m.streams { - entry.stream.closeForShutdown(err) - } - m.mutex.Unlock() - close(m.newStreamChan) -} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go deleted file mode 100644 index 4c7696a08..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map_incoming_generic.go +++ /dev/null @@ -1,190 +0,0 @@ -package quic - -import ( - "context" - "sync" - - "github.com/lucas-clemente/quic-go/internal/protocol" - "github.com/lucas-clemente/quic-go/internal/wire" -) - -// When a stream is deleted before it was accepted, we can't delete it from the map immediately. -// We need to wait until the application accepts it, and delete it then. -type itemEntry struct { - stream item - shouldDelete bool -} - -//go:generate genny -in $GOFILE -out streams_map_incoming_bidi.go gen "item=streamI Item=BidiStream streamTypeGeneric=protocol.StreamTypeBidi" -//go:generate genny -in $GOFILE -out streams_map_incoming_uni.go gen "item=receiveStreamI Item=UniStream streamTypeGeneric=protocol.StreamTypeUni" -type incomingItemsMap struct { - mutex sync.RWMutex - newStreamChan chan struct{} - - streams map[protocol.StreamNum]itemEntry - - nextStreamToAccept protocol.StreamNum // the next stream that will be returned by AcceptStream() - nextStreamToOpen protocol.StreamNum // the highest stream that the peer opened - maxStream protocol.StreamNum // the highest stream that the peer is allowed to open - maxNumStreams uint64 // maximum number of streams - - newStream func(protocol.StreamNum) item - queueMaxStreamID func(*wire.MaxStreamsFrame) - - closeErr error -} - -func newIncomingItemsMap( - newStream func(protocol.StreamNum) item, - maxStreams uint64, - queueControlFrame func(wire.Frame), -) *incomingItemsMap { - return &incomingItemsMap{ - newStreamChan: make(chan struct{}, 1), - streams: make(map[protocol.StreamNum]itemEntry), - maxStream: protocol.StreamNum(maxStreams), - maxNumStreams: maxStreams, - newStream: newStream, - nextStreamToOpen: 1, - nextStreamToAccept: 1, - queueMaxStreamID: func(f *wire.MaxStreamsFrame) { queueControlFrame(f) }, - } -} - -func (m *incomingItemsMap) AcceptStream(ctx context.Context) (item, error) { - // drain the newStreamChan, so we don't check the map twice if the stream doesn't exist - select { - case <-m.newStreamChan: - default: - } - - m.mutex.Lock() - - var num protocol.StreamNum - var entry itemEntry - for { - num = m.nextStreamToAccept - if m.closeErr != nil { - m.mutex.Unlock() - return nil, m.closeErr - } - var ok bool - entry, ok = m.streams[num] - if ok { - break - } - m.mutex.Unlock() - select { - case <-ctx.Done(): - return nil, ctx.Err() - case <-m.newStreamChan: - } - m.mutex.Lock() - } - m.nextStreamToAccept++ - // If this stream was completed before being accepted, we can delete it now. - if entry.shouldDelete { - if err := m.deleteStream(num); err != nil { - m.mutex.Unlock() - return nil, err - } - } - m.mutex.Unlock() - return entry.stream, nil -} - -func (m *incomingItemsMap) GetOrOpenStream(num protocol.StreamNum) (item, error) { - m.mutex.RLock() - if num > m.maxStream { - m.mutex.RUnlock() - return nil, streamError{ - message: "peer tried to open stream %d (current limit: %d)", - nums: []protocol.StreamNum{num, m.maxStream}, - } - } - // if the num is smaller than the highest we accepted - // * this stream exists in the map, and we can return it, or - // * this stream was already closed, then we can return the nil - if num < m.nextStreamToOpen { - var s item - // If the stream was already queued for deletion, and is just waiting to be accepted, don't return it. - if entry, ok := m.streams[num]; ok && !entry.shouldDelete { - s = entry.stream - } - m.mutex.RUnlock() - return s, nil - } - m.mutex.RUnlock() - - m.mutex.Lock() - // no need to check the two error conditions from above again - // * maxStream can only increase, so if the id was valid before, it definitely is valid now - // * highestStream is only modified by this function - for newNum := m.nextStreamToOpen; newNum <= num; newNum++ { - m.streams[newNum] = itemEntry{stream: m.newStream(newNum)} - select { - case m.newStreamChan <- struct{}{}: - default: - } - } - m.nextStreamToOpen = num + 1 - entry := m.streams[num] - m.mutex.Unlock() - return entry.stream, nil -} - -func (m *incomingItemsMap) DeleteStream(num protocol.StreamNum) error { - m.mutex.Lock() - defer m.mutex.Unlock() - - return m.deleteStream(num) -} - -func (m *incomingItemsMap) deleteStream(num protocol.StreamNum) error { - if _, ok := m.streams[num]; !ok { - return streamError{ - message: "tried to delete unknown incoming stream %d", - nums: []protocol.StreamNum{num}, - } - } - - // Don't delete this stream yet, if it was not yet accepted. - // Just save it to streamsToDelete map, to make sure it is deleted as soon as it gets accepted. - if num >= m.nextStreamToAccept { - entry, ok := m.streams[num] - if ok && entry.shouldDelete { - return streamError{ - message: "tried to delete incoming stream %d multiple times", - nums: []protocol.StreamNum{num}, - } - } - entry.shouldDelete = true - m.streams[num] = entry // can't assign to struct in map, so we need to reassign - return nil - } - - delete(m.streams, num) - // queue a MAX_STREAM_ID frame, giving the peer the option to open a new stream - if m.maxNumStreams > uint64(len(m.streams)) { - maxStream := m.nextStreamToOpen + protocol.StreamNum(m.maxNumStreams-uint64(len(m.streams))) - 1 - // Never send a value larger than protocol.MaxStreamCount. - if maxStream <= protocol.MaxStreamCount { - m.maxStream = maxStream - m.queueMaxStreamID(&wire.MaxStreamsFrame{ - Type: streamTypeGeneric, - MaxStreamNum: m.maxStream, - }) - } - } - return nil -} - -func (m *incomingItemsMap) CloseWithError(err error) { - m.mutex.Lock() - m.closeErr = err - for _, entry := range m.streams { - entry.stream.closeForShutdown(err) - } - m.mutex.Unlock() - close(m.newStreamChan) -} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing.go similarity index 74% rename from vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go rename to vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing.go index 8782364a5..d4f249f02 100644 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_uni.go +++ b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing.go @@ -1,7 +1,3 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - package quic import ( @@ -12,10 +8,16 @@ import ( "github.com/lucas-clemente/quic-go/internal/wire" ) -type outgoingUniStreamsMap struct { +type outgoingStream interface { + updateSendWindow(protocol.ByteCount) + closeForShutdown(error) +} + +type outgoingStreamsMap[T outgoingStream] struct { mutex sync.RWMutex - streams map[protocol.StreamNum]sendStreamI + streamType protocol.StreamType + streams map[protocol.StreamNum]T openQueue map[uint64]chan struct{} lowestInQueue uint64 @@ -25,18 +27,20 @@ type outgoingUniStreamsMap struct { maxStream protocol.StreamNum // the maximum stream ID we're allowed to open blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream - newStream func(protocol.StreamNum) sendStreamI + newStream func(protocol.StreamNum) T queueStreamIDBlocked func(*wire.StreamsBlockedFrame) closeErr error } -func newOutgoingUniStreamsMap( - newStream func(protocol.StreamNum) sendStreamI, +func newOutgoingStreamsMap[T outgoingStream]( + streamType protocol.StreamType, + newStream func(protocol.StreamNum) T, queueControlFrame func(wire.Frame), -) *outgoingUniStreamsMap { - return &outgoingUniStreamsMap{ - streams: make(map[protocol.StreamNum]sendStreamI), +) *outgoingStreamsMap[T] { + return &outgoingStreamsMap[T]{ + streamType: streamType, + streams: make(map[protocol.StreamNum]T), openQueue: make(map[uint64]chan struct{}), maxStream: protocol.InvalidStreamNum, nextStream: 1, @@ -45,32 +49,32 @@ func newOutgoingUniStreamsMap( } } -func (m *outgoingUniStreamsMap) OpenStream() (sendStreamI, error) { +func (m *outgoingStreamsMap[T]) OpenStream() (T, error) { m.mutex.Lock() defer m.mutex.Unlock() if m.closeErr != nil { - return nil, m.closeErr + return *new(T), m.closeErr } // if there are OpenStreamSync calls waiting, return an error here if len(m.openQueue) > 0 || m.nextStream > m.maxStream { m.maybeSendBlockedFrame() - return nil, streamOpenErr{errTooManyOpenStreams} + return *new(T), streamOpenErr{errTooManyOpenStreams} } return m.openStream(), nil } -func (m *outgoingUniStreamsMap) OpenStreamSync(ctx context.Context) (sendStreamI, error) { +func (m *outgoingStreamsMap[T]) OpenStreamSync(ctx context.Context) (T, error) { m.mutex.Lock() defer m.mutex.Unlock() if m.closeErr != nil { - return nil, m.closeErr + return *new(T), m.closeErr } if err := ctx.Err(); err != nil { - return nil, err + return *new(T), err } if len(m.openQueue) == 0 && m.nextStream <= m.maxStream { @@ -92,13 +96,13 @@ func (m *outgoingUniStreamsMap) OpenStreamSync(ctx context.Context) (sendStreamI case <-ctx.Done(): m.mutex.Lock() delete(m.openQueue, queuePos) - return nil, ctx.Err() + return *new(T), ctx.Err() case <-waitChan: } m.mutex.Lock() if m.closeErr != nil { - return nil, m.closeErr + return *new(T), m.closeErr } if m.nextStream > m.maxStream { // no stream available. Continue waiting @@ -112,7 +116,7 @@ func (m *outgoingUniStreamsMap) OpenStreamSync(ctx context.Context) (sendStreamI } } -func (m *outgoingUniStreamsMap) openStream() sendStreamI { +func (m *outgoingStreamsMap[T]) openStream() T { s := m.newStream(m.nextStream) m.streams[m.nextStream] = s m.nextStream++ @@ -121,7 +125,7 @@ func (m *outgoingUniStreamsMap) openStream() sendStreamI { // maybeSendBlockedFrame queues a STREAMS_BLOCKED frame for the current stream offset, // if we haven't sent one for this offset yet -func (m *outgoingUniStreamsMap) maybeSendBlockedFrame() { +func (m *outgoingStreamsMap[T]) maybeSendBlockedFrame() { if m.blockedSent { return } @@ -131,17 +135,17 @@ func (m *outgoingUniStreamsMap) maybeSendBlockedFrame() { streamNum = m.maxStream } m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ - Type: protocol.StreamTypeUni, + Type: m.streamType, StreamLimit: streamNum, }) m.blockedSent = true } -func (m *outgoingUniStreamsMap) GetStream(num protocol.StreamNum) (sendStreamI, error) { +func (m *outgoingStreamsMap[T]) GetStream(num protocol.StreamNum) (T, error) { m.mutex.RLock() if num >= m.nextStream { m.mutex.RUnlock() - return nil, streamError{ + return *new(T), streamError{ message: "peer attempted to open stream %d", nums: []protocol.StreamNum{num}, } @@ -151,7 +155,7 @@ func (m *outgoingUniStreamsMap) GetStream(num protocol.StreamNum) (sendStreamI, return s, nil } -func (m *outgoingUniStreamsMap) DeleteStream(num protocol.StreamNum) error { +func (m *outgoingStreamsMap[T]) DeleteStream(num protocol.StreamNum) error { m.mutex.Lock() defer m.mutex.Unlock() @@ -165,7 +169,7 @@ func (m *outgoingUniStreamsMap) DeleteStream(num protocol.StreamNum) error { return nil } -func (m *outgoingUniStreamsMap) SetMaxStream(num protocol.StreamNum) { +func (m *outgoingStreamsMap[T]) SetMaxStream(num protocol.StreamNum) { m.mutex.Lock() defer m.mutex.Unlock() @@ -183,7 +187,7 @@ func (m *outgoingUniStreamsMap) SetMaxStream(num protocol.StreamNum) { // UpdateSendWindow is called when the peer's transport parameters are received. // Only in the case of a 0-RTT handshake will we have open streams at this point. // We might need to update the send window, in case the server increased it. -func (m *outgoingUniStreamsMap) UpdateSendWindow(limit protocol.ByteCount) { +func (m *outgoingStreamsMap[T]) UpdateSendWindow(limit protocol.ByteCount) { m.mutex.Lock() for _, str := range m.streams { str.updateSendWindow(limit) @@ -192,7 +196,7 @@ func (m *outgoingUniStreamsMap) UpdateSendWindow(limit protocol.ByteCount) { } // unblockOpenSync unblocks the next OpenStreamSync go-routine to open a new stream -func (m *outgoingUniStreamsMap) unblockOpenSync() { +func (m *outgoingStreamsMap[T]) unblockOpenSync() { if len(m.openQueue) == 0 { return } @@ -211,7 +215,7 @@ func (m *outgoingUniStreamsMap) unblockOpenSync() { } } -func (m *outgoingUniStreamsMap) CloseWithError(err error) { +func (m *outgoingStreamsMap[T]) CloseWithError(err error) { m.mutex.Lock() m.closeErr = err for _, str := range m.streams { diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go deleted file mode 100644 index 3f7ec166a..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_bidi.go +++ /dev/null @@ -1,226 +0,0 @@ -// This file was automatically generated by genny. -// Any changes will be lost if this file is regenerated. -// see https://github.com/cheekybits/genny - -package quic - -import ( - "context" - "sync" - - "github.com/lucas-clemente/quic-go/internal/protocol" - "github.com/lucas-clemente/quic-go/internal/wire" -) - -type outgoingBidiStreamsMap struct { - mutex sync.RWMutex - - streams map[protocol.StreamNum]streamI - - openQueue map[uint64]chan struct{} - lowestInQueue uint64 - highestInQueue uint64 - - nextStream protocol.StreamNum // stream ID of the stream returned by OpenStream(Sync) - maxStream protocol.StreamNum // the maximum stream ID we're allowed to open - blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream - - newStream func(protocol.StreamNum) streamI - queueStreamIDBlocked func(*wire.StreamsBlockedFrame) - - closeErr error -} - -func newOutgoingBidiStreamsMap( - newStream func(protocol.StreamNum) streamI, - queueControlFrame func(wire.Frame), -) *outgoingBidiStreamsMap { - return &outgoingBidiStreamsMap{ - streams: make(map[protocol.StreamNum]streamI), - openQueue: make(map[uint64]chan struct{}), - maxStream: protocol.InvalidStreamNum, - nextStream: 1, - newStream: newStream, - queueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) }, - } -} - -func (m *outgoingBidiStreamsMap) OpenStream() (streamI, error) { - m.mutex.Lock() - defer m.mutex.Unlock() - - if m.closeErr != nil { - return nil, m.closeErr - } - - // if there are OpenStreamSync calls waiting, return an error here - if len(m.openQueue) > 0 || m.nextStream > m.maxStream { - m.maybeSendBlockedFrame() - return nil, streamOpenErr{errTooManyOpenStreams} - } - return m.openStream(), nil -} - -func (m *outgoingBidiStreamsMap) OpenStreamSync(ctx context.Context) (streamI, error) { - m.mutex.Lock() - defer m.mutex.Unlock() - - if m.closeErr != nil { - return nil, m.closeErr - } - - if err := ctx.Err(); err != nil { - return nil, err - } - - if len(m.openQueue) == 0 && m.nextStream <= m.maxStream { - return m.openStream(), nil - } - - waitChan := make(chan struct{}, 1) - queuePos := m.highestInQueue - m.highestInQueue++ - if len(m.openQueue) == 0 { - m.lowestInQueue = queuePos - } - m.openQueue[queuePos] = waitChan - m.maybeSendBlockedFrame() - - for { - m.mutex.Unlock() - select { - case <-ctx.Done(): - m.mutex.Lock() - delete(m.openQueue, queuePos) - return nil, ctx.Err() - case <-waitChan: - } - m.mutex.Lock() - - if m.closeErr != nil { - return nil, m.closeErr - } - if m.nextStream > m.maxStream { - // no stream available. Continue waiting - continue - } - str := m.openStream() - delete(m.openQueue, queuePos) - m.lowestInQueue = queuePos + 1 - m.unblockOpenSync() - return str, nil - } -} - -func (m *outgoingBidiStreamsMap) openStream() streamI { - s := m.newStream(m.nextStream) - m.streams[m.nextStream] = s - m.nextStream++ - return s -} - -// maybeSendBlockedFrame queues a STREAMS_BLOCKED frame for the current stream offset, -// if we haven't sent one for this offset yet -func (m *outgoingBidiStreamsMap) maybeSendBlockedFrame() { - if m.blockedSent { - return - } - - var streamNum protocol.StreamNum - if m.maxStream != protocol.InvalidStreamNum { - streamNum = m.maxStream - } - m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ - Type: protocol.StreamTypeBidi, - StreamLimit: streamNum, - }) - m.blockedSent = true -} - -func (m *outgoingBidiStreamsMap) GetStream(num protocol.StreamNum) (streamI, error) { - m.mutex.RLock() - if num >= m.nextStream { - m.mutex.RUnlock() - return nil, streamError{ - message: "peer attempted to open stream %d", - nums: []protocol.StreamNum{num}, - } - } - s := m.streams[num] - m.mutex.RUnlock() - return s, nil -} - -func (m *outgoingBidiStreamsMap) DeleteStream(num protocol.StreamNum) error { - m.mutex.Lock() - defer m.mutex.Unlock() - - if _, ok := m.streams[num]; !ok { - return streamError{ - message: "tried to delete unknown outgoing stream %d", - nums: []protocol.StreamNum{num}, - } - } - delete(m.streams, num) - return nil -} - -func (m *outgoingBidiStreamsMap) SetMaxStream(num protocol.StreamNum) { - m.mutex.Lock() - defer m.mutex.Unlock() - - if num <= m.maxStream { - return - } - m.maxStream = num - m.blockedSent = false - if m.maxStream < m.nextStream-1+protocol.StreamNum(len(m.openQueue)) { - m.maybeSendBlockedFrame() - } - m.unblockOpenSync() -} - -// UpdateSendWindow is called when the peer's transport parameters are received. -// Only in the case of a 0-RTT handshake will we have open streams at this point. -// We might need to update the send window, in case the server increased it. -func (m *outgoingBidiStreamsMap) UpdateSendWindow(limit protocol.ByteCount) { - m.mutex.Lock() - for _, str := range m.streams { - str.updateSendWindow(limit) - } - m.mutex.Unlock() -} - -// unblockOpenSync unblocks the next OpenStreamSync go-routine to open a new stream -func (m *outgoingBidiStreamsMap) unblockOpenSync() { - if len(m.openQueue) == 0 { - return - } - for qp := m.lowestInQueue; qp <= m.highestInQueue; qp++ { - c, ok := m.openQueue[qp] - if !ok { // entry was deleted because the context was canceled - continue - } - // unblockOpenSync is called both from OpenStreamSync and from SetMaxStream. - // It's sufficient to only unblock OpenStreamSync once. - select { - case c <- struct{}{}: - default: - } - return - } -} - -func (m *outgoingBidiStreamsMap) CloseWithError(err error) { - m.mutex.Lock() - m.closeErr = err - for _, str := range m.streams { - str.closeForShutdown(err) - } - for _, c := range m.openQueue { - if c != nil { - close(c) - } - } - m.mutex.Unlock() -} diff --git a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go b/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go deleted file mode 100644 index dde75043c..000000000 --- a/vendor/github.com/lucas-clemente/quic-go/streams_map_outgoing_generic.go +++ /dev/null @@ -1,224 +0,0 @@ -package quic - -import ( - "context" - "sync" - - "github.com/lucas-clemente/quic-go/internal/protocol" - "github.com/lucas-clemente/quic-go/internal/wire" -) - -//go:generate genny -in $GOFILE -out streams_map_outgoing_bidi.go gen "item=streamI Item=BidiStream streamTypeGeneric=protocol.StreamTypeBidi" -//go:generate genny -in $GOFILE -out streams_map_outgoing_uni.go gen "item=sendStreamI Item=UniStream streamTypeGeneric=protocol.StreamTypeUni" -type outgoingItemsMap struct { - mutex sync.RWMutex - - streams map[protocol.StreamNum]item - - openQueue map[uint64]chan struct{} - lowestInQueue uint64 - highestInQueue uint64 - - nextStream protocol.StreamNum // stream ID of the stream returned by OpenStream(Sync) - maxStream protocol.StreamNum // the maximum stream ID we're allowed to open - blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream - - newStream func(protocol.StreamNum) item - queueStreamIDBlocked func(*wire.StreamsBlockedFrame) - - closeErr error -} - -func newOutgoingItemsMap( - newStream func(protocol.StreamNum) item, - queueControlFrame func(wire.Frame), -) *outgoingItemsMap { - return &outgoingItemsMap{ - streams: make(map[protocol.StreamNum]item), - openQueue: make(map[uint64]chan struct{}), - maxStream: protocol.InvalidStreamNum, - nextStream: 1, - newStream: newStream, - queueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) }, - } -} - -func (m *outgoingItemsMap) OpenStream() (item, error) { - m.mutex.Lock() - defer m.mutex.Unlock() - - if m.closeErr != nil { - return nil, m.closeErr - } - - // if there are OpenStreamSync calls waiting, return an error here - if len(m.openQueue) > 0 || m.nextStream > m.maxStream { - m.maybeSendBlockedFrame() - return nil, streamOpenErr{errTooManyOpenStreams} - } - return m.openStream(), nil -} - -func (m *outgoingItemsMap) OpenStreamSync(ctx context.Context) (item, error) { - m.mutex.Lock() - defer m.mutex.Unlock() - - if m.closeErr != nil { - return nil, m.closeErr - } - - if err := ctx.Err(); err != nil { - return nil, err - } - - if len(m.openQueue) == 0 && m.nextStream <= m.maxStream { - return m.openStream(), nil - } - - waitChan := make(chan struct{}, 1) - queuePos := m.highestInQueue - m.highestInQueue++ - if len(m.openQueue) == 0 { - m.lowestInQueue = queuePos - } - m.openQueue[queuePos] = waitChan - m.maybeSendBlockedFrame() - - for { - m.mutex.Unlock() - select { - case <-ctx.Done(): - m.mutex.Lock() - delete(m.openQueue, queuePos) - return nil, ctx.Err() - case <-waitChan: - } - m.mutex.Lock() - - if m.closeErr != nil { - return nil, m.closeErr - } - if m.nextStream > m.maxStream { - // no stream available. Continue waiting - continue - } - str := m.openStream() - delete(m.openQueue, queuePos) - m.lowestInQueue = queuePos + 1 - m.unblockOpenSync() - return str, nil - } -} - -func (m *outgoingItemsMap) openStream() item { - s := m.newStream(m.nextStream) - m.streams[m.nextStream] = s - m.nextStream++ - return s -} - -// maybeSendBlockedFrame queues a STREAMS_BLOCKED frame for the current stream offset, -// if we haven't sent one for this offset yet -func (m *outgoingItemsMap) maybeSendBlockedFrame() { - if m.blockedSent { - return - } - - var streamNum protocol.StreamNum - if m.maxStream != protocol.InvalidStreamNum { - streamNum = m.maxStream - } - m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ - Type: streamTypeGeneric, - StreamLimit: streamNum, - }) - m.blockedSent = true -} - -func (m *outgoingItemsMap) GetStream(num protocol.StreamNum) (item, error) { - m.mutex.RLock() - if num >= m.nextStream { - m.mutex.RUnlock() - return nil, streamError{ - message: "peer attempted to open stream %d", - nums: []protocol.StreamNum{num}, - } - } - s := m.streams[num] - m.mutex.RUnlock() - return s, nil -} - -func (m *outgoingItemsMap) DeleteStream(num protocol.StreamNum) error { - m.mutex.Lock() - defer m.mutex.Unlock() - - if _, ok := m.streams[num]; !ok { - return streamError{ - message: "tried to delete unknown outgoing stream %d", - nums: []protocol.StreamNum{num}, - } - } - delete(m.streams, num) - return nil -} - -func (m *outgoingItemsMap) SetMaxStream(num protocol.StreamNum) { - m.mutex.Lock() - defer m.mutex.Unlock() - - if num <= m.maxStream { - return - } - m.maxStream = num - m.blockedSent = false - if m.maxStream < m.nextStream-1+protocol.StreamNum(len(m.openQueue)) { - m.maybeSendBlockedFrame() - } - m.unblockOpenSync() -} - -// UpdateSendWindow is called when the peer's transport parameters are received. -// Only in the case of a 0-RTT handshake will we have open streams at this point. -// We might need to update the send window, in case the server increased it. -func (m *outgoingItemsMap) UpdateSendWindow(limit protocol.ByteCount) { - m.mutex.Lock() - for _, str := range m.streams { - str.updateSendWindow(limit) - } - m.mutex.Unlock() -} - -// unblockOpenSync unblocks the next OpenStreamSync go-routine to open a new stream -func (m *outgoingItemsMap) unblockOpenSync() { - if len(m.openQueue) == 0 { - return - } - for qp := m.lowestInQueue; qp <= m.highestInQueue; qp++ { - c, ok := m.openQueue[qp] - if !ok { // entry was deleted because the context was canceled - continue - } - // unblockOpenSync is called both from OpenStreamSync and from SetMaxStream. - // It's sufficient to only unblock OpenStreamSync once. - select { - case c <- struct{}{}: - default: - } - return - } -} - -func (m *outgoingItemsMap) CloseWithError(err error) { - m.mutex.Lock() - m.closeErr = err - for _, str := range m.streams { - str.closeForShutdown(err) - } - for _, c := range m.openQueue { - if c != nil { - close(c) - } - } - m.mutex.Unlock() -} diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_df.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_df.go index ae9274d97..ef9f981ac 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_df.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_df.go @@ -1,5 +1,4 @@ //go:build !linux && !windows -// +build !linux,!windows package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_linux.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_linux.go index 17ac67f12..c4923164c 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_linux.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_windows.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_windows.go index 4649f6463..a83025c0c 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_windows.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_df_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_darwin.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_darwin.go index eabf489f1..7ad5f3af1 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_darwin.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_darwin.go @@ -1,5 +1,4 @@ //go:build darwin -// +build darwin package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_freebsd.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_freebsd.go index 0b3e8434b..8d16d0b91 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_freebsd.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_freebsd.go @@ -1,5 +1,4 @@ //go:build freebsd -// +build freebsd package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_linux.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_linux.go index 51bec9002..61c3f54ba 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_linux.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_helper_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_no_oob.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_no_oob.go index e3b0d11f6..7ab5040aa 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_no_oob.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_no_oob.go @@ -1,5 +1,4 @@ //go:build !darwin && !linux && !freebsd && !windows -// +build !darwin,!linux,!freebsd,!windows package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_oob.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_oob.go index acd74d023..f0f89cb59 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_oob.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_oob.go @@ -1,5 +1,4 @@ //go:build darwin || linux || freebsd -// +build darwin linux freebsd package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/sys_conn_windows.go b/vendor/github.com/lucas-clemente/quic-go/sys_conn_windows.go index f2cc22ab7..b003fe94a 100644 --- a/vendor/github.com/lucas-clemente/quic-go/sys_conn_windows.go +++ b/vendor/github.com/lucas-clemente/quic-go/sys_conn_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package quic diff --git a/vendor/github.com/lucas-clemente/quic-go/tools.go b/vendor/github.com/lucas-clemente/quic-go/tools.go index ee68fafbe..03ddd0630 100644 --- a/vendor/github.com/lucas-clemente/quic-go/tools.go +++ b/vendor/github.com/lucas-clemente/quic-go/tools.go @@ -1,9 +1,8 @@ //go:build tools -// +build tools package quic import ( - _ "github.com/cheekybits/genny" + _ "github.com/golang/mock/mockgen" _ "github.com/onsi/ginkgo/ginkgo" ) diff --git a/vendor/github.com/lucas-clemente/quic-go/zero_rtt_queue.go b/vendor/github.com/lucas-clemente/quic-go/zero_rtt_queue.go new file mode 100644 index 000000000..7ad7ee101 --- /dev/null +++ b/vendor/github.com/lucas-clemente/quic-go/zero_rtt_queue.go @@ -0,0 +1,34 @@ +package quic + +import ( + "time" + + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +type zeroRTTQueue struct { + queue []*receivedPacket + retireTimer *time.Timer +} + +var _ packetHandler = &zeroRTTQueue{} + +func (h *zeroRTTQueue) handlePacket(p *receivedPacket) { + if len(h.queue) < protocol.Max0RTTQueueLen { + h.queue = append(h.queue, p) + } +} +func (h *zeroRTTQueue) shutdown() {} +func (h *zeroRTTQueue) destroy(error) {} +func (h *zeroRTTQueue) getPerspective() protocol.Perspective { return protocol.PerspectiveClient } +func (h *zeroRTTQueue) EnqueueAll(sess packetHandler) { + for _, p := range h.queue { + sess.handlePacket(p) + } +} + +func (h *zeroRTTQueue) Clear() { + for _, p := range h.queue { + p.buffer.Release() + } +} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/README.md b/vendor/github.com/marten-seemann/qtls-go1-16/README.md deleted file mode 100644 index 0d318abe4..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# qtls - -[![Godoc Reference](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](https://godoc.org/github.com/marten-seemann/qtls) -[![CircleCI Build Status](https://img.shields.io/circleci/project/github/marten-seemann/qtls.svg?style=flat-square&label=CircleCI+build)](https://circleci.com/gh/marten-seemann/qtls) - -This repository contains a modified version of the standard library's TLS implementation, modified for the QUIC protocol. It is used by [quic-go](https://github.com/lucas-clemente/quic-go). diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/alert.go b/vendor/github.com/marten-seemann/qtls-go1-16/alert.go deleted file mode 100644 index 3feac79be..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/alert.go +++ /dev/null @@ -1,102 +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 qtls - -import "strconv" - -type alert uint8 - -// Alert is a TLS alert -type Alert = alert - -const ( - // alert level - alertLevelWarning = 1 - alertLevelError = 2 -) - -const ( - alertCloseNotify alert = 0 - alertUnexpectedMessage alert = 10 - alertBadRecordMAC alert = 20 - alertDecryptionFailed alert = 21 - alertRecordOverflow alert = 22 - alertDecompressionFailure alert = 30 - alertHandshakeFailure alert = 40 - alertBadCertificate alert = 42 - alertUnsupportedCertificate alert = 43 - alertCertificateRevoked alert = 44 - alertCertificateExpired alert = 45 - alertCertificateUnknown alert = 46 - alertIllegalParameter alert = 47 - alertUnknownCA alert = 48 - alertAccessDenied alert = 49 - alertDecodeError alert = 50 - alertDecryptError alert = 51 - alertExportRestriction alert = 60 - alertProtocolVersion alert = 70 - alertInsufficientSecurity alert = 71 - alertInternalError alert = 80 - alertInappropriateFallback alert = 86 - alertUserCanceled alert = 90 - alertNoRenegotiation alert = 100 - alertMissingExtension alert = 109 - alertUnsupportedExtension alert = 110 - alertCertificateUnobtainable alert = 111 - alertUnrecognizedName alert = 112 - alertBadCertificateStatusResponse alert = 113 - alertBadCertificateHashValue alert = 114 - alertUnknownPSKIdentity alert = 115 - alertCertificateRequired alert = 116 - alertNoApplicationProtocol alert = 120 -) - -var alertText = map[alert]string{ - alertCloseNotify: "close notify", - alertUnexpectedMessage: "unexpected message", - alertBadRecordMAC: "bad record MAC", - alertDecryptionFailed: "decryption failed", - alertRecordOverflow: "record overflow", - alertDecompressionFailure: "decompression failure", - alertHandshakeFailure: "handshake failure", - alertBadCertificate: "bad certificate", - alertUnsupportedCertificate: "unsupported certificate", - alertCertificateRevoked: "revoked certificate", - alertCertificateExpired: "expired certificate", - alertCertificateUnknown: "unknown certificate", - alertIllegalParameter: "illegal parameter", - alertUnknownCA: "unknown certificate authority", - alertAccessDenied: "access denied", - alertDecodeError: "error decoding message", - alertDecryptError: "error decrypting message", - alertExportRestriction: "export restriction", - alertProtocolVersion: "protocol version not supported", - alertInsufficientSecurity: "insufficient security level", - alertInternalError: "internal error", - alertInappropriateFallback: "inappropriate fallback", - alertUserCanceled: "user canceled", - alertNoRenegotiation: "no renegotiation", - alertMissingExtension: "missing extension", - alertUnsupportedExtension: "unsupported extension", - alertCertificateUnobtainable: "certificate unobtainable", - alertUnrecognizedName: "unrecognized name", - alertBadCertificateStatusResponse: "bad certificate status response", - alertBadCertificateHashValue: "bad certificate hash value", - alertUnknownPSKIdentity: "unknown PSK identity", - alertCertificateRequired: "certificate required", - alertNoApplicationProtocol: "no application protocol", -} - -func (e alert) String() string { - s, ok := alertText[e] - if ok { - return "tls: " + s - } - return "tls: alert(" + strconv.Itoa(int(e)) + ")" -} - -func (e alert) Error() string { - return e.String() -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/auth.go b/vendor/github.com/marten-seemann/qtls-go1-16/auth.go deleted file mode 100644 index 1ef675fd3..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/auth.go +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" - "crypto/rsa" - "errors" - "fmt" - "hash" - "io" -) - -// verifyHandshakeSignature verifies a signature against pre-hashed -// (if required) handshake contents. -func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error { - switch sigType { - case signatureECDSA: - pubKey, ok := pubkey.(*ecdsa.PublicKey) - if !ok { - return fmt.Errorf("expected an ECDSA public key, got %T", pubkey) - } - if !ecdsa.VerifyASN1(pubKey, signed, sig) { - return errors.New("ECDSA verification failure") - } - case signatureEd25519: - pubKey, ok := pubkey.(ed25519.PublicKey) - if !ok { - return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey) - } - if !ed25519.Verify(pubKey, signed, sig) { - return errors.New("Ed25519 verification failure") - } - case signaturePKCS1v15: - pubKey, ok := pubkey.(*rsa.PublicKey) - if !ok { - return fmt.Errorf("expected an RSA public key, got %T", pubkey) - } - if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil { - return err - } - case signatureRSAPSS: - pubKey, ok := pubkey.(*rsa.PublicKey) - if !ok { - return fmt.Errorf("expected an RSA public key, got %T", pubkey) - } - signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash} - if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil { - return err - } - default: - return errors.New("internal error: unknown signature type") - } - return nil -} - -const ( - serverSignatureContext = "TLS 1.3, server CertificateVerify\x00" - clientSignatureContext = "TLS 1.3, client CertificateVerify\x00" -) - -var signaturePadding = []byte{ - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -} - -// signedMessage returns the pre-hashed (if necessary) message to be signed by -// certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3. -func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) []byte { - if sigHash == directSigning { - b := &bytes.Buffer{} - b.Write(signaturePadding) - io.WriteString(b, context) - b.Write(transcript.Sum(nil)) - return b.Bytes() - } - h := sigHash.New() - h.Write(signaturePadding) - io.WriteString(h, context) - h.Write(transcript.Sum(nil)) - return h.Sum(nil) -} - -// typeAndHashFromSignatureScheme returns the corresponding signature type and -// crypto.Hash for a given TLS SignatureScheme. -func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) { - switch signatureAlgorithm { - case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512: - sigType = signaturePKCS1v15 - case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512: - sigType = signatureRSAPSS - case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512: - sigType = signatureECDSA - case Ed25519: - sigType = signatureEd25519 - default: - return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) - } - switch signatureAlgorithm { - case PKCS1WithSHA1, ECDSAWithSHA1: - hash = crypto.SHA1 - case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256: - hash = crypto.SHA256 - case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384: - hash = crypto.SHA384 - case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512: - hash = crypto.SHA512 - case Ed25519: - hash = directSigning - default: - return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) - } - return sigType, hash, nil -} - -// legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for -// a given public key used with TLS 1.0 and 1.1, before the introduction of -// signature algorithm negotiation. -func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) { - switch pub.(type) { - case *rsa.PublicKey: - return signaturePKCS1v15, crypto.MD5SHA1, nil - case *ecdsa.PublicKey: - return signatureECDSA, crypto.SHA1, nil - case ed25519.PublicKey: - // RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1, - // but it requires holding on to a handshake transcript to do a - // full signature, and not even OpenSSL bothers with the - // complexity, so we can't even test it properly. - return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2") - default: - return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub) - } -} - -var rsaSignatureSchemes = []struct { - scheme SignatureScheme - minModulusBytes int - maxVersion uint16 -}{ - // RSA-PSS is used with PSSSaltLengthEqualsHash, and requires - // emLen >= hLen + sLen + 2 - {PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13}, - {PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13}, - {PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13}, - // PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires - // emLen >= len(prefix) + hLen + 11 - // TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS. - {PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12}, - {PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12}, - {PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12}, - {PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12}, -} - -// signatureSchemesForCertificate returns the list of supported SignatureSchemes -// for a given certificate, based on the public key and the protocol version, -// and optionally filtered by its explicit SupportedSignatureAlgorithms. -// -// This function must be kept in sync with supportedSignatureAlgorithms. -func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme { - priv, ok := cert.PrivateKey.(crypto.Signer) - if !ok { - return nil - } - - var sigAlgs []SignatureScheme - switch pub := priv.Public().(type) { - case *ecdsa.PublicKey: - if version != VersionTLS13 { - // In TLS 1.2 and earlier, ECDSA algorithms are not - // constrained to a single curve. - sigAlgs = []SignatureScheme{ - ECDSAWithP256AndSHA256, - ECDSAWithP384AndSHA384, - ECDSAWithP521AndSHA512, - ECDSAWithSHA1, - } - break - } - switch pub.Curve { - case elliptic.P256(): - sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256} - case elliptic.P384(): - sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384} - case elliptic.P521(): - sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512} - default: - return nil - } - case *rsa.PublicKey: - size := pub.Size() - sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes)) - for _, candidate := range rsaSignatureSchemes { - if size >= candidate.minModulusBytes && version <= candidate.maxVersion { - sigAlgs = append(sigAlgs, candidate.scheme) - } - } - case ed25519.PublicKey: - sigAlgs = []SignatureScheme{Ed25519} - default: - return nil - } - - if cert.SupportedSignatureAlgorithms != nil { - var filteredSigAlgs []SignatureScheme - for _, sigAlg := range sigAlgs { - if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) { - filteredSigAlgs = append(filteredSigAlgs, sigAlg) - } - } - return filteredSigAlgs - } - return sigAlgs -} - -// selectSignatureScheme picks a SignatureScheme from the peer's preference list -// that works with the selected certificate. It's only called for protocol -// versions that support signature algorithms, so TLS 1.2 and 1.3. -func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) { - supportedAlgs := signatureSchemesForCertificate(vers, c) - if len(supportedAlgs) == 0 { - return 0, unsupportedCertificateError(c) - } - if len(peerAlgs) == 0 && vers == VersionTLS12 { - // For TLS 1.2, if the client didn't send signature_algorithms then we - // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1. - peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1} - } - // Pick signature scheme in the peer's preference order, as our - // preference order is not configurable. - for _, preferredAlg := range peerAlgs { - if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { - return preferredAlg, nil - } - } - return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms") -} - -// unsupportedCertificateError returns a helpful error for certificates with -// an unsupported private key. -func unsupportedCertificateError(cert *Certificate) error { - switch cert.PrivateKey.(type) { - case rsa.PrivateKey, ecdsa.PrivateKey: - return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T", - cert.PrivateKey, cert.PrivateKey) - case *ed25519.PrivateKey: - return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey") - } - - signer, ok := cert.PrivateKey.(crypto.Signer) - if !ok { - return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer", - cert.PrivateKey) - } - - switch pub := signer.Public().(type) { - case *ecdsa.PublicKey: - switch pub.Curve { - case elliptic.P256(): - case elliptic.P384(): - case elliptic.P521(): - default: - return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name) - } - case *rsa.PublicKey: - return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms") - case ed25519.PublicKey: - default: - return fmt.Errorf("tls: unsupported certificate key (%T)", pub) - } - - if cert.SupportedSignatureAlgorithms != nil { - return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms") - } - - return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey) -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/cipher_suites.go b/vendor/github.com/marten-seemann/qtls-go1-16/cipher_suites.go deleted file mode 100644 index 78f80107f..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/cipher_suites.go +++ /dev/null @@ -1,532 +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 qtls - -import ( - "crypto" - "crypto/aes" - "crypto/cipher" - "crypto/des" - "crypto/hmac" - "crypto/rc4" - "crypto/sha1" - "crypto/sha256" - "crypto/x509" - "fmt" - "hash" - - "golang.org/x/crypto/chacha20poly1305" -) - -// CipherSuite is a TLS cipher suite. Note that most functions in this package -// accept and expose cipher suite IDs instead of this type. -type CipherSuite struct { - ID uint16 - Name string - - // Supported versions is the list of TLS protocol versions that can - // negotiate this cipher suite. - SupportedVersions []uint16 - - // Insecure is true if the cipher suite has known security issues - // due to its primitives, design, or implementation. - Insecure bool -} - -var ( - supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12} - supportedOnlyTLS12 = []uint16{VersionTLS12} - supportedOnlyTLS13 = []uint16{VersionTLS13} -) - -// CipherSuites returns a list of cipher suites currently implemented by this -// package, excluding those with security issues, which are returned by -// InsecureCipherSuites. -// -// The list is sorted by ID. Note that the default cipher suites selected by -// this package might depend on logic that can't be captured by a static list. -func CipherSuites() []*CipherSuite { - return []*CipherSuite{ - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false}, - {TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, - {TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, - {TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, - {TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, - - {TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false}, - {TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false}, - {TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false}, - - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, - } -} - -// InsecureCipherSuites returns a list of cipher suites currently implemented by -// this package and which have security issues. -// -// Most applications should not use the cipher suites in this list, and should -// only use those returned by CipherSuites. -func InsecureCipherSuites() []*CipherSuite { - // RC4 suites are broken because RC4 is. - // CBC-SHA256 suites have no Lucky13 countermeasures. - return []*CipherSuite{ - {TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, - {TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, - } -} - -// CipherSuiteName returns the standard name for the passed cipher suite ID -// (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation -// of the ID value if the cipher suite is not implemented by this package. -func CipherSuiteName(id uint16) string { - for _, c := range CipherSuites() { - if c.ID == id { - return c.Name - } - } - for _, c := range InsecureCipherSuites() { - if c.ID == id { - return c.Name - } - } - return fmt.Sprintf("0x%04X", id) -} - -// a keyAgreement implements the client and server side of a TLS key agreement -// protocol by generating and processing key exchange messages. -type keyAgreement interface { - // On the server side, the first two methods are called in order. - - // In the case that the key agreement protocol doesn't use a - // ServerKeyExchange message, generateServerKeyExchange can return nil, - // nil. - generateServerKeyExchange(*config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) - processClientKeyExchange(*config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) - - // On the client side, the next two methods are called in order. - - // This method may not be called if the server doesn't send a - // ServerKeyExchange message. - processServerKeyExchange(*config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error - generateClientKeyExchange(*config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) -} - -const ( - // suiteECDHE indicates that the cipher suite involves elliptic curve - // Diffie-Hellman. This means that it should only be selected when the - // client indicates that it supports ECC with a curve and point format - // that we're happy with. - suiteECDHE = 1 << iota - // suiteECSign indicates that the cipher suite involves an ECDSA or - // EdDSA signature and therefore may only be selected when the server's - // certificate is ECDSA or EdDSA. If this is not set then the cipher suite - // is RSA based. - suiteECSign - // suiteTLS12 indicates that the cipher suite should only be advertised - // and accepted when using TLS 1.2. - suiteTLS12 - // suiteSHA384 indicates that the cipher suite uses SHA384 as the - // handshake hash. - suiteSHA384 - // suiteDefaultOff indicates that this cipher suite is not included by - // default. - suiteDefaultOff -) - -// A cipherSuite is a specific combination of key agreement, cipher and MAC function. -type cipherSuite struct { - id uint16 - // the lengths, in bytes, of the key material needed for each component. - keyLen int - macLen int - ivLen int - ka func(version uint16) keyAgreement - // flags is a bitmask of the suite* values, above. - flags int - cipher func(key, iv []byte, isRead bool) interface{} - mac func(key []byte) hash.Hash - aead func(key, fixedNonce []byte) aead -} - -var cipherSuites = []*cipherSuite{ - // Ciphersuite order is chosen so that ECDHE comes before plain RSA and - // AEADs are the top preference. - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12 | suiteDefaultOff, cipherAES, macSHA256, nil}, - {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, - - // RC4-based cipher suites are disabled by default. - {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, suiteDefaultOff, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE | suiteDefaultOff, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteDefaultOff, cipherRC4, macSHA1, nil}, -} - -// selectCipherSuite returns the first cipher suite from ids which is also in -// supportedIDs and passes the ok filter. -func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite { - for _, id := range ids { - candidate := cipherSuiteByID(id) - if candidate == nil || !ok(candidate) { - continue - } - - for _, suppID := range supportedIDs { - if id == suppID { - return candidate - } - } - } - return nil -} - -// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash -// algorithm to be used with HKDF. See RFC 8446, Appendix B.4. -type cipherSuiteTLS13 struct { - id uint16 - keyLen int - aead func(key, fixedNonce []byte) aead - hash crypto.Hash -} - -type CipherSuiteTLS13 struct { - ID uint16 - KeyLen int - Hash crypto.Hash - AEAD func(key, fixedNonce []byte) cipher.AEAD -} - -func (c *CipherSuiteTLS13) IVLen() int { - return aeadNonceLength -} - -var cipherSuitesTLS13 = []*cipherSuiteTLS13{ - {TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256}, - {TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256}, - {TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384}, -} - -func cipherRC4(key, iv []byte, isRead bool) interface{} { - cipher, _ := rc4.NewCipher(key) - return cipher -} - -func cipher3DES(key, iv []byte, isRead bool) interface{} { - block, _ := des.NewTripleDESCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -func cipherAES(key, iv []byte, isRead bool) interface{} { - block, _ := aes.NewCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -// macSHA1 returns a SHA-1 based constant time MAC. -func macSHA1(key []byte) hash.Hash { - return hmac.New(newConstantTimeHash(sha1.New), key) -} - -// macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and -// is currently only used in disabled-by-default cipher suites. -func macSHA256(key []byte) hash.Hash { - return hmac.New(sha256.New, key) -} - -type aead interface { - cipher.AEAD - - // explicitNonceLen returns the number of bytes of explicit nonce - // included in each record. This is eight for older AEADs and - // zero for modern ones. - explicitNonceLen() int -} - -const ( - aeadNonceLength = 12 - noncePrefixLength = 4 -) - -// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to -// each call. -type prefixNonceAEAD struct { - // nonce contains the fixed part of the nonce in the first four bytes. - nonce [aeadNonceLength]byte - aead cipher.AEAD -} - -func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength } -func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() } -func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() } - -func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { - copy(f.nonce[4:], nonce) - return f.aead.Seal(out, f.nonce[:], plaintext, additionalData) -} - -func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { - copy(f.nonce[4:], nonce) - return f.aead.Open(out, f.nonce[:], ciphertext, additionalData) -} - -// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce -// before each call. -type xorNonceAEAD struct { - nonceMask [aeadNonceLength]byte - aead cipher.AEAD -} - -func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number -func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() } -func (f *xorNonceAEAD) explicitNonceLen() int { return 0 } - -func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData) - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - - return result -} - -func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData) - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - - return result, err -} - -func aeadAESGCM(key, noncePrefix []byte) aead { - if len(noncePrefix) != noncePrefixLength { - panic("tls: internal error: wrong nonce length") - } - aes, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - aead, err := cipher.NewGCM(aes) - if err != nil { - panic(err) - } - - ret := &prefixNonceAEAD{aead: aead} - copy(ret.nonce[:], noncePrefix) - return ret -} - -// AEADAESGCMTLS13 creates a new AES-GCM AEAD for TLS 1.3 -func AEADAESGCMTLS13(key, fixedNonce []byte) cipher.AEAD { - return aeadAESGCMTLS13(key, fixedNonce) -} - -func aeadAESGCMTLS13(key, nonceMask []byte) aead { - if len(nonceMask) != aeadNonceLength { - panic("tls: internal error: wrong nonce length") - } - aes, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - aead, err := cipher.NewGCM(aes) - if err != nil { - panic(err) - } - - ret := &xorNonceAEAD{aead: aead} - copy(ret.nonceMask[:], nonceMask) - return ret -} - -func aeadChaCha20Poly1305(key, nonceMask []byte) aead { - if len(nonceMask) != aeadNonceLength { - panic("tls: internal error: wrong nonce length") - } - aead, err := chacha20poly1305.New(key) - if err != nil { - panic(err) - } - - ret := &xorNonceAEAD{aead: aead} - copy(ret.nonceMask[:], nonceMask) - return ret -} - -type constantTimeHash interface { - hash.Hash - ConstantTimeSum(b []byte) []byte -} - -// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces -// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC. -type cthWrapper struct { - h constantTimeHash -} - -func (c *cthWrapper) Size() int { return c.h.Size() } -func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() } -func (c *cthWrapper) Reset() { c.h.Reset() } -func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) } -func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) } - -func newConstantTimeHash(h func() hash.Hash) func() hash.Hash { - return func() hash.Hash { - return &cthWrapper{h().(constantTimeHash)} - } -} - -// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3. -func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte { - h.Reset() - h.Write(seq) - h.Write(header) - h.Write(data) - res := h.Sum(out) - if extra != nil { - h.Write(extra) - } - return res -} - -func rsaKA(version uint16) keyAgreement { - return rsaKeyAgreement{} -} - -func ecdheECDSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - isRSA: false, - version: version, - } -} - -func ecdheRSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - isRSA: true, - version: version, - } -} - -// mutualCipherSuite returns a cipherSuite given a list of supported -// ciphersuites and the id requested by the peer. -func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { - for _, id := range have { - if id == want { - return cipherSuiteByID(id) - } - } - return nil -} - -func cipherSuiteByID(id uint16) *cipherSuite { - for _, cipherSuite := range cipherSuites { - if cipherSuite.id == id { - return cipherSuite - } - } - return nil -} - -func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 { - for _, id := range have { - if id == want { - return cipherSuiteTLS13ByID(id) - } - } - return nil -} - -func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 { - for _, cipherSuite := range cipherSuitesTLS13 { - if cipherSuite.id == id { - return cipherSuite - } - } - return nil -} - -// A list of cipher suite IDs that are, or have been, implemented by this -// package. -// -// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml -const ( - // TLS 1.0 - 1.2 cipher suites. - TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a - TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f - TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c - TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c - TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a - TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9 - - // TLS 1.3 cipher suites. - TLS_AES_128_GCM_SHA256 uint16 = 0x1301 - TLS_AES_256_GCM_SHA384 uint16 = 0x1302 - TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303 - - // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator - // that the client is doing version fallback. See RFC 7507. - TLS_FALLBACK_SCSV uint16 = 0x5600 - - // Legacy names for the corresponding cipher suites with the correct _SHA256 - // suffix, retained for backward compatibility. - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 -) diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/common.go b/vendor/github.com/marten-seemann/qtls-go1-16/common.go deleted file mode 100644 index 266f93fef..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/common.go +++ /dev/null @@ -1,1576 +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 qtls - -import ( - "bytes" - "container/list" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "crypto/sha512" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "io" - "net" - "sort" - "strings" - "sync" - "time" -) - -const ( - VersionTLS10 = 0x0301 - VersionTLS11 = 0x0302 - VersionTLS12 = 0x0303 - VersionTLS13 = 0x0304 - - // Deprecated: SSLv3 is cryptographically broken, and is no longer - // supported by this package. See golang.org/issue/32716. - VersionSSL30 = 0x0300 -) - -const ( - maxPlaintext = 16384 // maximum plaintext payload length - maxCiphertext = 16384 + 2048 // maximum ciphertext payload length - maxCiphertextTLS13 = 16384 + 256 // maximum ciphertext length in TLS 1.3 - recordHeaderLen = 5 // record header length - maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) - maxUselessRecords = 16 // maximum number of consecutive non-advancing records -) - -// TLS record types. -type recordType uint8 - -const ( - recordTypeChangeCipherSpec recordType = 20 - recordTypeAlert recordType = 21 - recordTypeHandshake recordType = 22 - recordTypeApplicationData recordType = 23 -) - -// TLS handshake message types. -const ( - typeHelloRequest uint8 = 0 - typeClientHello uint8 = 1 - typeServerHello uint8 = 2 - typeNewSessionTicket uint8 = 4 - typeEndOfEarlyData uint8 = 5 - typeEncryptedExtensions uint8 = 8 - typeCertificate uint8 = 11 - typeServerKeyExchange uint8 = 12 - typeCertificateRequest uint8 = 13 - typeServerHelloDone uint8 = 14 - typeCertificateVerify uint8 = 15 - typeClientKeyExchange uint8 = 16 - typeFinished uint8 = 20 - typeCertificateStatus uint8 = 22 - typeKeyUpdate uint8 = 24 - typeNextProtocol uint8 = 67 // Not IANA assigned - typeMessageHash uint8 = 254 // synthetic message -) - -// TLS compression types. -const ( - compressionNone uint8 = 0 -) - -type Extension struct { - Type uint16 - Data []byte -} - -// TLS extension numbers -const ( - extensionServerName uint16 = 0 - extensionStatusRequest uint16 = 5 - extensionSupportedCurves uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7 - extensionSupportedPoints uint16 = 11 - extensionSignatureAlgorithms uint16 = 13 - extensionALPN uint16 = 16 - extensionSCT uint16 = 18 - extensionSessionTicket uint16 = 35 - extensionPreSharedKey uint16 = 41 - extensionEarlyData uint16 = 42 - extensionSupportedVersions uint16 = 43 - extensionCookie uint16 = 44 - extensionPSKModes uint16 = 45 - extensionCertificateAuthorities uint16 = 47 - extensionSignatureAlgorithmsCert uint16 = 50 - extensionKeyShare uint16 = 51 - extensionRenegotiationInfo uint16 = 0xff01 -) - -// TLS signaling cipher suite values -const ( - scsvRenegotiation uint16 = 0x00ff -) - -type EncryptionLevel uint8 - -const ( - EncryptionHandshake EncryptionLevel = iota - Encryption0RTT - EncryptionApplication -) - -// CurveID is a tls.CurveID -type CurveID = tls.CurveID - -const ( - CurveP256 CurveID = 23 - CurveP384 CurveID = 24 - CurveP521 CurveID = 25 - X25519 CurveID = 29 -) - -// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8. -type keyShare struct { - group CurveID - data []byte -} - -// TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9. -const ( - pskModePlain uint8 = 0 - pskModeDHE uint8 = 1 -) - -// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved -// session. See RFC 8446, Section 4.2.11. -type pskIdentity struct { - label []byte - obfuscatedTicketAge uint32 -} - -// TLS Elliptic Curve Point Formats -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 -const ( - pointFormatUncompressed uint8 = 0 -) - -// TLS CertificateStatusType (RFC 3546) -const ( - statusTypeOCSP uint8 = 1 -) - -// Certificate types (for certificateRequestMsg) -const ( - certTypeRSASign = 1 - certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3. -) - -// Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with -// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do. -const ( - signaturePKCS1v15 uint8 = iota + 225 - signatureRSAPSS - signatureECDSA - signatureEd25519 -) - -// directSigning is a standard Hash value that signals that no pre-hashing -// should be performed, and that the input should be signed directly. It is the -// hash function associated with the Ed25519 signature scheme. -var directSigning crypto.Hash = 0 - -// supportedSignatureAlgorithms contains the signature and hash algorithms that -// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+ -// CertificateRequest. The two fields are merged to match with TLS 1.3. -// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc. -var supportedSignatureAlgorithms = []SignatureScheme{ - PSSWithSHA256, - ECDSAWithP256AndSHA256, - Ed25519, - PSSWithSHA384, - PSSWithSHA512, - PKCS1WithSHA256, - PKCS1WithSHA384, - PKCS1WithSHA512, - ECDSAWithP384AndSHA384, - ECDSAWithP521AndSHA512, - PKCS1WithSHA1, - ECDSAWithSHA1, -} - -// helloRetryRequestRandom is set as the Random value of a ServerHello -// to signal that the message is actually a HelloRetryRequest. -var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3. - 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, - 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, - 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, - 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C, -} - -const ( - // downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server - // random as a downgrade protection if the server would be capable of - // negotiating a higher version. See RFC 8446, Section 4.1.3. - downgradeCanaryTLS12 = "DOWNGRD\x01" - downgradeCanaryTLS11 = "DOWNGRD\x00" -) - -// testingOnlyForceDowngradeCanary is set in tests to force the server side to -// include downgrade canaries even if it's using its highers supported version. -var testingOnlyForceDowngradeCanary bool - -type ConnectionState = tls.ConnectionState - -// ConnectionState records basic TLS details about the connection. -type connectionState struct { - // Version is the TLS version used by the connection (e.g. VersionTLS12). - Version uint16 - - // HandshakeComplete is true if the handshake has concluded. - HandshakeComplete bool - - // DidResume is true if this connection was successfully resumed from a - // previous session with a session ticket or similar mechanism. - DidResume bool - - // CipherSuite is the cipher suite negotiated for the connection (e.g. - // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256). - CipherSuite uint16 - - // NegotiatedProtocol is the application protocol negotiated with ALPN. - NegotiatedProtocol string - - // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation. - // - // Deprecated: this value is always true. - NegotiatedProtocolIsMutual bool - - // ServerName is the value of the Server Name Indication extension sent by - // the client. It's available both on the server and on the client side. - ServerName string - - // PeerCertificates are the parsed certificates sent by the peer, in the - // order in which they were sent. The first element is the leaf certificate - // that the connection is verified against. - // - // On the client side, it can't be empty. On the server side, it can be - // empty if Config.ClientAuth is not RequireAnyClientCert or - // RequireAndVerifyClientCert. - PeerCertificates []*x509.Certificate - - // VerifiedChains is a list of one or more chains where the first element is - // PeerCertificates[0] and the last element is from Config.RootCAs (on the - // client side) or Config.ClientCAs (on the server side). - // - // On the client side, it's set if Config.InsecureSkipVerify is false. On - // the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven - // (and the peer provided a certificate) or RequireAndVerifyClientCert. - VerifiedChains [][]*x509.Certificate - - // SignedCertificateTimestamps is a list of SCTs provided by the peer - // through the TLS handshake for the leaf certificate, if any. - SignedCertificateTimestamps [][]byte - - // OCSPResponse is a stapled Online Certificate Status Protocol (OCSP) - // response provided by the peer for the leaf certificate, if any. - OCSPResponse []byte - - // TLSUnique contains the "tls-unique" channel binding value (see RFC 5929, - // Section 3). This value will be nil for TLS 1.3 connections and for all - // resumed connections. - // - // Deprecated: there are conditions in which this value might not be unique - // to a connection. See the Security Considerations sections of RFC 5705 and - // RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings. - TLSUnique []byte - - // ekm is a closure exposed via ExportKeyingMaterial. - ekm func(label string, context []byte, length int) ([]byte, error) -} - -type ConnectionStateWith0RTT struct { - ConnectionState - - Used0RTT bool // true if 0-RTT was both offered and accepted -} - -// ClientAuthType is tls.ClientAuthType -type ClientAuthType = tls.ClientAuthType - -const ( - NoClientCert = tls.NoClientCert - RequestClientCert = tls.RequestClientCert - RequireAnyClientCert = tls.RequireAnyClientCert - VerifyClientCertIfGiven = tls.VerifyClientCertIfGiven - RequireAndVerifyClientCert = tls.RequireAndVerifyClientCert -) - -// requiresClientCert reports whether the ClientAuthType requires a client -// certificate to be provided. -func requiresClientCert(c ClientAuthType) bool { - switch c { - case RequireAnyClientCert, RequireAndVerifyClientCert: - return true - default: - return false - } -} - -// ClientSessionState contains the state needed by clients to resume TLS -// sessions. -type ClientSessionState = tls.ClientSessionState - -type clientSessionState struct { - sessionTicket []uint8 // Encrypted ticket used for session resumption with server - vers uint16 // TLS version negotiated for the session - cipherSuite uint16 // Ciphersuite negotiated for the session - masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret - serverCertificates []*x509.Certificate // Certificate chain presented by the server - verifiedChains [][]*x509.Certificate // Certificate chains we built for verification - receivedAt time.Time // When the session ticket was received from the server - ocspResponse []byte // Stapled OCSP response presented by the server - scts [][]byte // SCTs presented by the server - - // TLS 1.3 fields. - nonce []byte // Ticket nonce sent by the server, to derive PSK - useBy time.Time // Expiration of the ticket lifetime as set by the server - ageAdd uint32 // Random obfuscation factor for sending the ticket age -} - -// ClientSessionCache is a cache of ClientSessionState objects that can be used -// by a client to resume a TLS session with a given server. ClientSessionCache -// implementations should expect to be called concurrently from different -// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not -// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which -// are supported via this interface. -//go:generate sh -c "mockgen -package qtls -destination mock_client_session_cache_test.go github.com/marten-seemann/qtls-go1-15 ClientSessionCache" -type ClientSessionCache = tls.ClientSessionCache - -// SignatureScheme is a tls.SignatureScheme -type SignatureScheme = tls.SignatureScheme - -const ( - // RSASSA-PKCS1-v1_5 algorithms. - PKCS1WithSHA256 SignatureScheme = 0x0401 - PKCS1WithSHA384 SignatureScheme = 0x0501 - PKCS1WithSHA512 SignatureScheme = 0x0601 - - // RSASSA-PSS algorithms with public key OID rsaEncryption. - PSSWithSHA256 SignatureScheme = 0x0804 - PSSWithSHA384 SignatureScheme = 0x0805 - PSSWithSHA512 SignatureScheme = 0x0806 - - // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3. - ECDSAWithP256AndSHA256 SignatureScheme = 0x0403 - ECDSAWithP384AndSHA384 SignatureScheme = 0x0503 - ECDSAWithP521AndSHA512 SignatureScheme = 0x0603 - - // EdDSA algorithms. - Ed25519 SignatureScheme = 0x0807 - - // Legacy signature and hash algorithms for TLS 1.2. - PKCS1WithSHA1 SignatureScheme = 0x0201 - ECDSAWithSHA1 SignatureScheme = 0x0203 -) - -// ClientHelloInfo contains information from a ClientHello message in order to -// guide application logic in the GetCertificate and GetConfigForClient callbacks. -type ClientHelloInfo = tls.ClientHelloInfo - -type clientHelloInfo struct { - // CipherSuites lists the CipherSuites supported by the client (e.g. - // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256). - CipherSuites []uint16 - - // ServerName indicates the name of the server requested by the client - // in order to support virtual hosting. ServerName is only set if the - // client is using SNI (see RFC 4366, Section 3.1). - ServerName string - - // SupportedCurves lists the elliptic curves supported by the client. - // SupportedCurves is set only if the Supported Elliptic Curves - // Extension is being used (see RFC 4492, Section 5.1.1). - SupportedCurves []CurveID - - // SupportedPoints lists the point formats supported by the client. - // SupportedPoints is set only if the Supported Point Formats Extension - // is being used (see RFC 4492, Section 5.1.2). - SupportedPoints []uint8 - - // SignatureSchemes lists the signature and hash schemes that the client - // is willing to verify. SignatureSchemes is set only if the Signature - // Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1). - SignatureSchemes []SignatureScheme - - // SupportedProtos lists the application protocols supported by the client. - // SupportedProtos is set only if the Application-Layer Protocol - // Negotiation Extension is being used (see RFC 7301, Section 3.1). - // - // Servers can select a protocol by setting Config.NextProtos in a - // GetConfigForClient return value. - SupportedProtos []string - - // SupportedVersions lists the TLS versions supported by the client. - // For TLS versions less than 1.3, this is extrapolated from the max - // version advertised by the client, so values other than the greatest - // might be rejected if used. - SupportedVersions []uint16 - - // Conn is the underlying net.Conn for the connection. Do not read - // from, or write to, this connection; that will cause the TLS - // connection to fail. - Conn net.Conn - - // config is embedded by the GetCertificate or GetConfigForClient caller, - // for use with SupportsCertificate. - config *Config -} - -// CertificateRequestInfo contains information from a server's -// CertificateRequest message, which is used to demand a certificate and proof -// of control from a client. -type CertificateRequestInfo = tls.CertificateRequestInfo - -type certificateRequestInfo struct { - // AcceptableCAs contains zero or more, DER-encoded, X.501 - // Distinguished Names. These are the names of root or intermediate CAs - // that the server wishes the returned certificate to be signed by. An - // empty slice indicates that the server has no preference. - AcceptableCAs [][]byte - - // SignatureSchemes lists the signature schemes that the server is - // willing to verify. - SignatureSchemes []SignatureScheme - - // Version is the TLS version that was negotiated for this connection. - Version uint16 -} - -// RenegotiationSupport enumerates the different levels of support for TLS -// renegotiation. TLS renegotiation is the act of performing subsequent -// handshakes on a connection after the first. This significantly complicates -// the state machine and has been the source of numerous, subtle security -// issues. Initiating a renegotiation is not supported, but support for -// accepting renegotiation requests may be enabled. -// -// Even when enabled, the server may not change its identity between handshakes -// (i.e. the leaf certificate must be the same). Additionally, concurrent -// handshake and application data flow is not permitted so renegotiation can -// only be used with protocols that synchronise with the renegotiation, such as -// HTTPS. -// -// Renegotiation is not defined in TLS 1.3. -type RenegotiationSupport = tls.RenegotiationSupport - -const ( - // RenegotiateNever disables renegotiation. - RenegotiateNever = tls.RenegotiateNever - - // RenegotiateOnceAsClient allows a remote server to request - // renegotiation once per connection. - RenegotiateOnceAsClient = tls.RenegotiateOnceAsClient - - // RenegotiateFreelyAsClient allows a remote server to repeatedly - // request renegotiation. - RenegotiateFreelyAsClient = tls.RenegotiateFreelyAsClient -) - -// A Config structure is used to configure a TLS client or server. -// After one has been passed to a TLS function it must not be -// modified. A Config may be reused; the tls package will also not -// modify it. -type Config = tls.Config - -type config struct { - // Rand provides the source of entropy for nonces and RSA blinding. - // If Rand is nil, TLS uses the cryptographic random reader in package - // crypto/rand. - // The Reader must be safe for use by multiple goroutines. - Rand io.Reader - - // Time returns the current time as the number of seconds since the epoch. - // If Time is nil, TLS uses time.Now. - Time func() time.Time - - // Certificates contains one or more certificate chains to present to the - // other side of the connection. The first certificate compatible with the - // peer's requirements is selected automatically. - // - // Server configurations must set one of Certificates, GetCertificate or - // GetConfigForClient. Clients doing client-authentication may set either - // Certificates or GetClientCertificate. - // - // Note: if there are multiple Certificates, and they don't have the - // optional field Leaf set, certificate selection will incur a significant - // per-handshake performance cost. - Certificates []Certificate - - // NameToCertificate maps from a certificate name to an element of - // Certificates. Note that a certificate name can be of the form - // '*.example.com' and so doesn't have to be a domain name as such. - // - // Deprecated: NameToCertificate only allows associating a single - // certificate with a given name. Leave this field nil to let the library - // select the first compatible chain from Certificates. - NameToCertificate map[string]*Certificate - - // GetCertificate returns a Certificate based on the given - // ClientHelloInfo. It will only be called if the client supplies SNI - // information or if Certificates is empty. - // - // If GetCertificate is nil or returns nil, then the certificate is - // retrieved from NameToCertificate. If NameToCertificate is nil, the - // best element of Certificates will be used. - GetCertificate func(*ClientHelloInfo) (*Certificate, error) - - // GetClientCertificate, if not nil, is called when a server requests a - // certificate from a client. If set, the contents of Certificates will - // be ignored. - // - // If GetClientCertificate returns an error, the handshake will be - // aborted and that error will be returned. Otherwise - // GetClientCertificate must return a non-nil Certificate. If - // Certificate.Certificate is empty then no certificate will be sent to - // the server. If this is unacceptable to the server then it may abort - // the handshake. - // - // GetClientCertificate may be called multiple times for the same - // connection if renegotiation occurs or if TLS 1.3 is in use. - GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error) - - // GetConfigForClient, if not nil, is called after a ClientHello is - // received from a client. It may return a non-nil Config in order to - // change the Config that will be used to handle this connection. If - // the returned Config is nil, the original Config will be used. The - // Config returned by this callback may not be subsequently modified. - // - // If GetConfigForClient is nil, the Config passed to Server() will be - // used for all connections. - // - // If SessionTicketKey was explicitly set on the returned Config, or if - // SetSessionTicketKeys was called on the returned Config, those keys will - // be used. Otherwise, the original Config keys will be used (and possibly - // rotated if they are automatically managed). - GetConfigForClient func(*ClientHelloInfo) (*Config, error) - - // VerifyPeerCertificate, if not nil, is called after normal - // certificate verification by either a TLS client or server. It - // receives the raw ASN.1 certificates provided by the peer and also - // any verified chains that normal processing found. If it returns a - // non-nil error, the handshake is aborted and that error results. - // - // If normal verification fails then the handshake will abort before - // considering this callback. If normal verification is disabled by - // setting InsecureSkipVerify, or (for a server) when ClientAuth is - // RequestClientCert or RequireAnyClientCert, then this callback will - // be considered but the verifiedChains argument will always be nil. - VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error - - // VerifyConnection, if not nil, is called after normal certificate - // verification and after VerifyPeerCertificate by either a TLS client - // or server. If it returns a non-nil error, the handshake is aborted - // and that error results. - // - // If normal verification fails then the handshake will abort before - // considering this callback. This callback will run for all connections - // regardless of InsecureSkipVerify or ClientAuth settings. - VerifyConnection func(ConnectionState) error - - // RootCAs defines the set of root certificate authorities - // that clients use when verifying server certificates. - // If RootCAs is nil, TLS uses the host's root CA set. - RootCAs *x509.CertPool - - // NextProtos is a list of supported application level protocols, in - // order of preference. - NextProtos []string - - // ServerName is used to verify the hostname on the returned - // certificates unless InsecureSkipVerify is given. It is also included - // in the client's handshake to support virtual hosting unless it is - // an IP address. - ServerName string - - // ClientAuth determines the server's policy for - // TLS Client Authentication. The default is NoClientCert. - ClientAuth ClientAuthType - - // ClientCAs defines the set of root certificate authorities - // that servers use if required to verify a client certificate - // by the policy in ClientAuth. - ClientCAs *x509.CertPool - - // InsecureSkipVerify controls whether a client verifies the server's - // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls - // accepts any certificate presented by the server and any host name in that - // certificate. In this mode, TLS is susceptible to machine-in-the-middle - // attacks unless custom verification is used. This should be used only for - // testing or in combination with VerifyConnection or VerifyPeerCertificate. - InsecureSkipVerify bool - - // CipherSuites is a list of supported cipher suites for TLS versions up to - // TLS 1.2. If CipherSuites is nil, a default list of secure cipher suites - // is used, with a preference order based on hardware performance. The - // default cipher suites might change over Go versions. Note that TLS 1.3 - // ciphersuites are not configurable. - CipherSuites []uint16 - - // PreferServerCipherSuites controls whether the server selects the - // client's most preferred ciphersuite, or the server's most preferred - // ciphersuite. If true then the server's preference, as expressed in - // the order of elements in CipherSuites, is used. - PreferServerCipherSuites bool - - // SessionTicketsDisabled may be set to true to disable session ticket and - // PSK (resumption) support. Note that on clients, session ticket support is - // also disabled if ClientSessionCache is nil. - SessionTicketsDisabled bool - - // SessionTicketKey is used by TLS servers to provide session resumption. - // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled - // with random data before the first server handshake. - // - // Deprecated: if this field is left at zero, session ticket keys will be - // automatically rotated every day and dropped after seven days. For - // customizing the rotation schedule or synchronizing servers that are - // terminating connections for the same host, use SetSessionTicketKeys. - SessionTicketKey [32]byte - - // ClientSessionCache is a cache of ClientSessionState entries for TLS - // session resumption. It is only used by clients. - ClientSessionCache ClientSessionCache - - // MinVersion contains the minimum TLS version that is acceptable. - // If zero, TLS 1.0 is currently taken as the minimum. - MinVersion uint16 - - // MaxVersion contains the maximum TLS version that is acceptable. - // If zero, the maximum version supported by this package is used, - // which is currently TLS 1.3. - MaxVersion uint16 - - // CurvePreferences contains the elliptic curves that will be used in - // an ECDHE handshake, in preference order. If empty, the default will - // be used. The client will use the first preference as the type for - // its key share in TLS 1.3. This may change in the future. - CurvePreferences []CurveID - - // DynamicRecordSizingDisabled disables adaptive sizing of TLS records. - // When true, the largest possible TLS record size is always used. When - // false, the size of TLS records may be adjusted in an attempt to - // improve latency. - DynamicRecordSizingDisabled bool - - // Renegotiation controls what types of renegotiation are supported. - // The default, none, is correct for the vast majority of applications. - Renegotiation RenegotiationSupport - - // KeyLogWriter optionally specifies a destination for TLS master secrets - // in NSS key log format that can be used to allow external programs - // such as Wireshark to decrypt TLS connections. - // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. - // Use of KeyLogWriter compromises security and should only be - // used for debugging. - KeyLogWriter io.Writer - - // mutex protects sessionTicketKeys and autoSessionTicketKeys. - mutex sync.RWMutex - // sessionTicketKeys contains zero or more ticket keys. If set, it means the - // the keys were set with SessionTicketKey or SetSessionTicketKeys. The - // first key is used for new tickets and any subsequent keys can be used to - // decrypt old tickets. The slice contents are not protected by the mutex - // and are immutable. - sessionTicketKeys []ticketKey - // autoSessionTicketKeys is like sessionTicketKeys but is owned by the - // auto-rotation logic. See Config.ticketKeys. - autoSessionTicketKeys []ticketKey -} - -// A RecordLayer handles encrypting and decrypting of TLS messages. -type RecordLayer interface { - SetReadKey(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte) - SetWriteKey(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte) - ReadHandshakeMessage() ([]byte, error) - WriteRecord([]byte) (int, error) - SendAlert(uint8) -} - -type ExtraConfig struct { - // GetExtensions, if not nil, is called before a message that allows - // sending of extensions is sent. - // Currently only implemented for the ClientHello message (for the client) - // and for the EncryptedExtensions message (for the server). - // Only valid for TLS 1.3. - GetExtensions func(handshakeMessageType uint8) []Extension - - // ReceivedExtensions, if not nil, is called when a message that allows the - // inclusion of extensions is received. - // It is called with an empty slice of extensions, if the message didn't - // contain any extensions. - // Currently only implemented for the ClientHello message (sent by the - // client) and for the EncryptedExtensions message (sent by the server). - // Only valid for TLS 1.3. - ReceivedExtensions func(handshakeMessageType uint8, exts []Extension) - - // AlternativeRecordLayer is used by QUIC - AlternativeRecordLayer RecordLayer - - // Enforce the selection of a supported application protocol. - // Only works for TLS 1.3. - // If enabled, client and server have to agree on an application protocol. - // Otherwise, connection establishment fails. - EnforceNextProtoSelection bool - - // If MaxEarlyData is greater than 0, the client will be allowed to send early - // data when resuming a session. - // Requires the AlternativeRecordLayer to be set. - // - // It has no meaning on the client. - MaxEarlyData uint32 - - // The Accept0RTT callback is called when the client offers 0-RTT. - // The server then has to decide if it wants to accept or reject 0-RTT. - // It is only used for servers. - Accept0RTT func(appData []byte) bool - - // 0RTTRejected is called when the server rejectes 0-RTT. - // It is only used for clients. - Rejected0RTT func() - - // If set, the client will export the 0-RTT key when resuming a session that - // allows sending of early data. - // Requires the AlternativeRecordLayer to be set. - // - // It has no meaning to the server. - Enable0RTT bool - - // Is called when the client saves a session ticket to the session ticket. - // This gives the application the opportunity to save some data along with the ticket, - // which can be restored when the session ticket is used. - GetAppDataForSessionState func() []byte - - // Is called when the client uses a session ticket. - // Restores the application data that was saved earlier on GetAppDataForSessionTicket. - SetAppDataFromSessionState func([]byte) -} - -// Clone clones. -func (c *ExtraConfig) Clone() *ExtraConfig { - return &ExtraConfig{ - GetExtensions: c.GetExtensions, - ReceivedExtensions: c.ReceivedExtensions, - AlternativeRecordLayer: c.AlternativeRecordLayer, - EnforceNextProtoSelection: c.EnforceNextProtoSelection, - MaxEarlyData: c.MaxEarlyData, - Enable0RTT: c.Enable0RTT, - Accept0RTT: c.Accept0RTT, - Rejected0RTT: c.Rejected0RTT, - GetAppDataForSessionState: c.GetAppDataForSessionState, - SetAppDataFromSessionState: c.SetAppDataFromSessionState, - } -} - -func (c *ExtraConfig) usesAlternativeRecordLayer() bool { - return c != nil && c.AlternativeRecordLayer != nil -} - -const ( - // ticketKeyNameLen is the number of bytes of identifier that is prepended to - // an encrypted session ticket in order to identify the key used to encrypt it. - ticketKeyNameLen = 16 - - // ticketKeyLifetime is how long a ticket key remains valid and can be used to - // resume a client connection. - ticketKeyLifetime = 7 * 24 * time.Hour // 7 days - - // ticketKeyRotation is how often the server should rotate the session ticket key - // that is used for new tickets. - ticketKeyRotation = 24 * time.Hour -) - -// ticketKey is the internal representation of a session ticket key. -type ticketKey struct { - // keyName is an opaque byte string that serves to identify the session - // ticket key. It's exposed as plaintext in every session ticket. - keyName [ticketKeyNameLen]byte - aesKey [16]byte - hmacKey [16]byte - // created is the time at which this ticket key was created. See Config.ticketKeys. - created time.Time -} - -// ticketKeyFromBytes converts from the external representation of a session -// ticket key to a ticketKey. Externally, session ticket keys are 32 random -// bytes and this function expands that into sufficient name and key material. -func (c *config) ticketKeyFromBytes(b [32]byte) (key ticketKey) { - hashed := sha512.Sum512(b[:]) - copy(key.keyName[:], hashed[:ticketKeyNameLen]) - copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16]) - copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32]) - key.created = c.time() - return key -} - -// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session -// ticket, and the lifetime we set for tickets we send. -const maxSessionTicketLifetime = 7 * 24 * time.Hour - -// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is -// being used concurrently by a TLS client or server. -func (c *config) Clone() *config { - if c == nil { - return nil - } - c.mutex.RLock() - defer c.mutex.RUnlock() - return &config{ - Rand: c.Rand, - Time: c.Time, - Certificates: c.Certificates, - NameToCertificate: c.NameToCertificate, - GetCertificate: c.GetCertificate, - GetClientCertificate: c.GetClientCertificate, - GetConfigForClient: c.GetConfigForClient, - VerifyPeerCertificate: c.VerifyPeerCertificate, - VerifyConnection: c.VerifyConnection, - RootCAs: c.RootCAs, - NextProtos: c.NextProtos, - ServerName: c.ServerName, - ClientAuth: c.ClientAuth, - ClientCAs: c.ClientCAs, - InsecureSkipVerify: c.InsecureSkipVerify, - CipherSuites: c.CipherSuites, - PreferServerCipherSuites: c.PreferServerCipherSuites, - SessionTicketsDisabled: c.SessionTicketsDisabled, - SessionTicketKey: c.SessionTicketKey, - ClientSessionCache: c.ClientSessionCache, - MinVersion: c.MinVersion, - MaxVersion: c.MaxVersion, - CurvePreferences: c.CurvePreferences, - DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, - Renegotiation: c.Renegotiation, - KeyLogWriter: c.KeyLogWriter, - sessionTicketKeys: c.sessionTicketKeys, - autoSessionTicketKeys: c.autoSessionTicketKeys, - } -} - -// deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was -// randomized for backwards compatibility but is not in use. -var deprecatedSessionTicketKey = []byte("DEPRECATED") - -// initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is -// randomized if empty, and that sessionTicketKeys is populated from it otherwise. -func (c *config) initLegacySessionTicketKeyRLocked() { - // Don't write if SessionTicketKey is already defined as our deprecated string, - // or if it is defined by the user but sessionTicketKeys is already set. - if c.SessionTicketKey != [32]byte{} && - (bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) { - return - } - - // We need to write some data, so get an exclusive lock and re-check any conditions. - c.mutex.RUnlock() - defer c.mutex.RLock() - c.mutex.Lock() - defer c.mutex.Unlock() - if c.SessionTicketKey == [32]byte{} { - if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { - panic(fmt.Sprintf("tls: unable to generate random session ticket key: %v", err)) - } - // Write the deprecated prefix at the beginning so we know we created - // it. This key with the DEPRECATED prefix isn't used as an actual - // session ticket key, and is only randomized in case the application - // reuses it for some reason. - copy(c.SessionTicketKey[:], deprecatedSessionTicketKey) - } else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 { - c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)} - } - -} - -// ticketKeys returns the ticketKeys for this connection. -// If configForClient has explicitly set keys, those will -// be returned. Otherwise, the keys on c will be used and -// may be rotated if auto-managed. -// During rotation, any expired session ticket keys are deleted from -// c.sessionTicketKeys. If the session ticket key that is currently -// encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys) -// is not fresh, then a new session ticket key will be -// created and prepended to c.sessionTicketKeys. -func (c *config) ticketKeys(configForClient *config) []ticketKey { - // If the ConfigForClient callback returned a Config with explicitly set - // keys, use those, otherwise just use the original Config. - if configForClient != nil { - configForClient.mutex.RLock() - if configForClient.SessionTicketsDisabled { - return nil - } - configForClient.initLegacySessionTicketKeyRLocked() - if len(configForClient.sessionTicketKeys) != 0 { - ret := configForClient.sessionTicketKeys - configForClient.mutex.RUnlock() - return ret - } - configForClient.mutex.RUnlock() - } - - c.mutex.RLock() - defer c.mutex.RUnlock() - if c.SessionTicketsDisabled { - return nil - } - c.initLegacySessionTicketKeyRLocked() - if len(c.sessionTicketKeys) != 0 { - return c.sessionTicketKeys - } - // Fast path for the common case where the key is fresh enough. - if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation { - return c.autoSessionTicketKeys - } - - // autoSessionTicketKeys are managed by auto-rotation. - c.mutex.RUnlock() - defer c.mutex.RLock() - c.mutex.Lock() - defer c.mutex.Unlock() - // Re-check the condition in case it changed since obtaining the new lock. - if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation { - var newKey [32]byte - if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil { - panic(fmt.Sprintf("unable to generate random session ticket key: %v", err)) - } - valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1) - valid = append(valid, c.ticketKeyFromBytes(newKey)) - for _, k := range c.autoSessionTicketKeys { - // While rotating the current key, also remove any expired ones. - if c.time().Sub(k.created) < ticketKeyLifetime { - valid = append(valid, k) - } - } - c.autoSessionTicketKeys = valid - } - return c.autoSessionTicketKeys -} - -// SetSessionTicketKeys updates the session ticket keys for a server. -// -// The first key will be used when creating new tickets, while all keys can be -// used for decrypting tickets. It is safe to call this function while the -// server is running in order to rotate the session ticket keys. The function -// will panic if keys is empty. -// -// Calling this function will turn off automatic session ticket key rotation. -// -// If multiple servers are terminating connections for the same host they should -// all have the same session ticket keys. If the session ticket keys leaks, -// previously recorded and future TLS connections using those keys might be -// compromised. -func (c *config) SetSessionTicketKeys(keys [][32]byte) { - if len(keys) == 0 { - panic("tls: keys must have at least one key") - } - - newKeys := make([]ticketKey, len(keys)) - for i, bytes := range keys { - newKeys[i] = c.ticketKeyFromBytes(bytes) - } - - c.mutex.Lock() - c.sessionTicketKeys = newKeys - c.mutex.Unlock() -} - -func (c *config) rand() io.Reader { - r := c.Rand - if r == nil { - return rand.Reader - } - return r -} - -func (c *config) time() time.Time { - t := c.Time - if t == nil { - t = time.Now - } - return t() -} - -func (c *config) cipherSuites() []uint16 { - s := c.CipherSuites - if s == nil { - s = defaultCipherSuites() - } - return s -} - -var supportedVersions = []uint16{ - VersionTLS13, - VersionTLS12, - VersionTLS11, - VersionTLS10, -} - -func (c *config) supportedVersions() []uint16 { - versions := make([]uint16, 0, len(supportedVersions)) - for _, v := range supportedVersions { - if c != nil && c.MinVersion != 0 && v < c.MinVersion { - continue - } - if c != nil && c.MaxVersion != 0 && v > c.MaxVersion { - continue - } - versions = append(versions, v) - } - return versions -} - -func (c *config) maxSupportedVersion() uint16 { - supportedVersions := c.supportedVersions() - if len(supportedVersions) == 0 { - return 0 - } - return supportedVersions[0] -} - -// supportedVersionsFromMax returns a list of supported versions derived from a -// legacy maximum version value. Note that only versions supported by this -// library are returned. Any newer peer will use supportedVersions anyway. -func supportedVersionsFromMax(maxVersion uint16) []uint16 { - versions := make([]uint16, 0, len(supportedVersions)) - for _, v := range supportedVersions { - if v > maxVersion { - continue - } - versions = append(versions, v) - } - return versions -} - -var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521} - -func (c *config) curvePreferences() []CurveID { - if c == nil || len(c.CurvePreferences) == 0 { - return defaultCurvePreferences - } - return c.CurvePreferences -} - -func (c *config) supportsCurve(curve CurveID) bool { - for _, cc := range c.curvePreferences() { - if cc == curve { - return true - } - } - return false -} - -// mutualVersion returns the protocol version to use given the advertised -// versions of the peer. Priority is given to the peer preference order. -func (c *config) mutualVersion(peerVersions []uint16) (uint16, bool) { - supportedVersions := c.supportedVersions() - for _, peerVersion := range peerVersions { - for _, v := range supportedVersions { - if v == peerVersion { - return v, true - } - } - } - return 0, false -} - -var errNoCertificates = errors.New("tls: no certificates configured") - -// getCertificate returns the best certificate for the given ClientHelloInfo, -// defaulting to the first element of c.Certificates. -func (c *config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) { - if c.GetCertificate != nil && - (len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) { - cert, err := c.GetCertificate(clientHello) - if cert != nil || err != nil { - return cert, err - } - } - - if len(c.Certificates) == 0 { - return nil, errNoCertificates - } - - if len(c.Certificates) == 1 { - // There's only one choice, so no point doing any work. - return &c.Certificates[0], nil - } - - if c.NameToCertificate != nil { - name := strings.ToLower(clientHello.ServerName) - if cert, ok := c.NameToCertificate[name]; ok { - return cert, nil - } - if len(name) > 0 { - labels := strings.Split(name, ".") - labels[0] = "*" - wildcardName := strings.Join(labels, ".") - if cert, ok := c.NameToCertificate[wildcardName]; ok { - return cert, nil - } - } - } - - for _, cert := range c.Certificates { - if err := clientHello.SupportsCertificate(&cert); err == nil { - return &cert, nil - } - } - - // If nothing matches, return the first certificate. - return &c.Certificates[0], nil -} - -// SupportsCertificate returns nil if the provided certificate is supported by -// the client that sent the ClientHello. Otherwise, it returns an error -// describing the reason for the incompatibility. -// -// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate -// callback, this method will take into account the associated Config. Note that -// if GetConfigForClient returns a different Config, the change can't be -// accounted for by this method. -// -// This function will call x509.ParseCertificate unless c.Leaf is set, which can -// incur a significant performance cost. -func (chi *clientHelloInfo) SupportsCertificate(c *Certificate) error { - // Note we don't currently support certificate_authorities nor - // signature_algorithms_cert, and don't check the algorithms of the - // signatures on the chain (which anyway are a SHOULD, see RFC 8446, - // Section 4.4.2.2). - - config := chi.config - if config == nil { - config = &Config{} - } - conf := fromConfig(config) - vers, ok := conf.mutualVersion(chi.SupportedVersions) - if !ok { - return errors.New("no mutually supported protocol versions") - } - - // If the client specified the name they are trying to connect to, the - // certificate needs to be valid for it. - if chi.ServerName != "" { - x509Cert, err := leafCertificate(c) - if err != nil { - return fmt.Errorf("failed to parse certificate: %w", err) - } - if err := x509Cert.VerifyHostname(chi.ServerName); err != nil { - return fmt.Errorf("certificate is not valid for requested server name: %w", err) - } - } - - // supportsRSAFallback returns nil if the certificate and connection support - // the static RSA key exchange, and unsupported otherwise. The logic for - // supporting static RSA is completely disjoint from the logic for - // supporting signed key exchanges, so we just check it as a fallback. - supportsRSAFallback := func(unsupported error) error { - // TLS 1.3 dropped support for the static RSA key exchange. - if vers == VersionTLS13 { - return unsupported - } - // The static RSA key exchange works by decrypting a challenge with the - // RSA private key, not by signing, so check the PrivateKey implements - // crypto.Decrypter, like *rsa.PrivateKey does. - if priv, ok := c.PrivateKey.(crypto.Decrypter); ok { - if _, ok := priv.Public().(*rsa.PublicKey); !ok { - return unsupported - } - } else { - return unsupported - } - // Finally, there needs to be a mutual cipher suite that uses the static - // RSA key exchange instead of ECDHE. - rsaCipherSuite := selectCipherSuite(chi.CipherSuites, conf.cipherSuites(), func(c *cipherSuite) bool { - if c.flags&suiteECDHE != 0 { - return false - } - if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { - return false - } - return true - }) - if rsaCipherSuite == nil { - return unsupported - } - return nil - } - - // If the client sent the signature_algorithms extension, ensure it supports - // schemes we can use with this certificate and TLS version. - if len(chi.SignatureSchemes) > 0 { - if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil { - return supportsRSAFallback(err) - } - } - - // In TLS 1.3 we are done because supported_groups is only relevant to the - // ECDHE computation, point format negotiation is removed, cipher suites are - // only relevant to the AEAD choice, and static RSA does not exist. - if vers == VersionTLS13 { - return nil - } - - // The only signed key exchange we support is ECDHE. - if !supportsECDHE(conf, chi.SupportedCurves, chi.SupportedPoints) { - return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange")) - } - - var ecdsaCipherSuite bool - if priv, ok := c.PrivateKey.(crypto.Signer); ok { - switch pub := priv.Public().(type) { - case *ecdsa.PublicKey: - var curve CurveID - switch pub.Curve { - case elliptic.P256(): - curve = CurveP256 - case elliptic.P384(): - curve = CurveP384 - case elliptic.P521(): - curve = CurveP521 - default: - return supportsRSAFallback(unsupportedCertificateError(c)) - } - var curveOk bool - for _, c := range chi.SupportedCurves { - if c == curve && conf.supportsCurve(c) { - curveOk = true - break - } - } - if !curveOk { - return errors.New("client doesn't support certificate curve") - } - ecdsaCipherSuite = true - case ed25519.PublicKey: - if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 { - return errors.New("connection doesn't support Ed25519") - } - ecdsaCipherSuite = true - case *rsa.PublicKey: - default: - return supportsRSAFallback(unsupportedCertificateError(c)) - } - } else { - return supportsRSAFallback(unsupportedCertificateError(c)) - } - - // Make sure that there is a mutually supported cipher suite that works with - // this certificate. Cipher suite selection will then apply the logic in - // reverse to pick it. See also serverHandshakeState.cipherSuiteOk. - cipherSuite := selectCipherSuite(chi.CipherSuites, conf.cipherSuites(), func(c *cipherSuite) bool { - if c.flags&suiteECDHE == 0 { - return false - } - if c.flags&suiteECSign != 0 { - if !ecdsaCipherSuite { - return false - } - } else { - if ecdsaCipherSuite { - return false - } - } - if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { - return false - } - return true - }) - if cipherSuite == nil { - return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate")) - } - - return nil -} - -// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate -// from the CommonName and SubjectAlternateName fields of each of the leaf -// certificates. -// -// Deprecated: NameToCertificate only allows associating a single certificate -// with a given name. Leave that field nil to let the library select the first -// compatible chain from Certificates. -func (c *config) BuildNameToCertificate() { - c.NameToCertificate = make(map[string]*Certificate) - for i := range c.Certificates { - cert := &c.Certificates[i] - x509Cert, err := leafCertificate(cert) - if err != nil { - continue - } - // If SANs are *not* present, some clients will consider the certificate - // valid for the name in the Common Name. - if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 { - c.NameToCertificate[x509Cert.Subject.CommonName] = cert - } - for _, san := range x509Cert.DNSNames { - c.NameToCertificate[san] = cert - } - } -} - -const ( - keyLogLabelTLS12 = "CLIENT_RANDOM" - keyLogLabelEarlyTraffic = "CLIENT_EARLY_TRAFFIC_SECRET" - keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET" - keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET" - keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0" - keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0" -) - -func (c *config) writeKeyLog(label string, clientRandom, secret []byte) error { - if c.KeyLogWriter == nil { - return nil - } - - logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret)) - - writerMutex.Lock() - _, err := c.KeyLogWriter.Write(logLine) - writerMutex.Unlock() - - return err -} - -// writerMutex protects all KeyLogWriters globally. It is rarely enabled, -// and is only for debugging, so a global mutex saves space. -var writerMutex sync.Mutex - -// A Certificate is a chain of one or more certificates, leaf first. -type Certificate = tls.Certificate - -// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing -// the corresponding c.Certificate[0]. -func leafCertificate(c *Certificate) (*x509.Certificate, error) { - if c.Leaf != nil { - return c.Leaf, nil - } - return x509.ParseCertificate(c.Certificate[0]) -} - -type handshakeMessage interface { - marshal() []byte - unmarshal([]byte) bool -} - -// lruSessionCache is a ClientSessionCache implementation that uses an LRU -// caching strategy. -type lruSessionCache struct { - sync.Mutex - - m map[string]*list.Element - q *list.List - capacity int -} - -type lruSessionCacheEntry struct { - sessionKey string - state *ClientSessionState -} - -// NewLRUClientSessionCache returns a ClientSessionCache with the given -// capacity that uses an LRU strategy. If capacity is < 1, a default capacity -// is used instead. -func NewLRUClientSessionCache(capacity int) ClientSessionCache { - const defaultSessionCacheCapacity = 64 - - if capacity < 1 { - capacity = defaultSessionCacheCapacity - } - return &lruSessionCache{ - m: make(map[string]*list.Element), - q: list.New(), - capacity: capacity, - } -} - -// Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry -// corresponding to sessionKey is removed from the cache instead. -func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) { - c.Lock() - defer c.Unlock() - - if elem, ok := c.m[sessionKey]; ok { - if cs == nil { - c.q.Remove(elem) - delete(c.m, sessionKey) - } else { - entry := elem.Value.(*lruSessionCacheEntry) - entry.state = cs - c.q.MoveToFront(elem) - } - return - } - - if c.q.Len() < c.capacity { - entry := &lruSessionCacheEntry{sessionKey, cs} - c.m[sessionKey] = c.q.PushFront(entry) - return - } - - elem := c.q.Back() - entry := elem.Value.(*lruSessionCacheEntry) - delete(c.m, entry.sessionKey) - entry.sessionKey = sessionKey - entry.state = cs - c.q.MoveToFront(elem) - c.m[sessionKey] = elem -} - -// Get returns the ClientSessionState value associated with a given key. It -// returns (nil, false) if no value is found. -func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) { - c.Lock() - defer c.Unlock() - - if elem, ok := c.m[sessionKey]; ok { - c.q.MoveToFront(elem) - return elem.Value.(*lruSessionCacheEntry).state, true - } - return nil, false -} - -var emptyConfig Config - -func defaultConfig() *Config { - return &emptyConfig -} - -var ( - once sync.Once - varDefaultCipherSuites []uint16 - varDefaultCipherSuitesTLS13 []uint16 -) - -func defaultCipherSuites() []uint16 { - once.Do(initDefaultCipherSuites) - return varDefaultCipherSuites -} - -func defaultCipherSuitesTLS13() []uint16 { - once.Do(initDefaultCipherSuites) - return varDefaultCipherSuitesTLS13 -} - -func initDefaultCipherSuites() { - var topCipherSuites []uint16 - - if hasAESGCMHardwareSupport { - // If AES-GCM hardware is provided then prioritise AES-GCM - // cipher suites. - topCipherSuites = []uint16{ - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, - } - varDefaultCipherSuitesTLS13 = []uint16{ - TLS_AES_128_GCM_SHA256, - TLS_CHACHA20_POLY1305_SHA256, - TLS_AES_256_GCM_SHA384, - } - } else { - // Without AES-GCM hardware, we put the ChaCha20-Poly1305 - // cipher suites first. - topCipherSuites = []uint16{ - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - } - varDefaultCipherSuitesTLS13 = []uint16{ - TLS_CHACHA20_POLY1305_SHA256, - TLS_AES_128_GCM_SHA256, - TLS_AES_256_GCM_SHA384, - } - } - - varDefaultCipherSuites = make([]uint16, 0, len(cipherSuites)) - varDefaultCipherSuites = append(varDefaultCipherSuites, topCipherSuites...) - -NextCipherSuite: - for _, suite := range cipherSuites { - if suite.flags&suiteDefaultOff != 0 { - continue - } - for _, existing := range varDefaultCipherSuites { - if existing == suite.id { - continue NextCipherSuite - } - } - varDefaultCipherSuites = append(varDefaultCipherSuites, suite.id) - } -} - -func unexpectedMessageError(wanted, got interface{}) error { - return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted) -} - -func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool { - for _, s := range supportedSignatureAlgorithms { - if s == sigAlg { - return true - } - } - return false -} - -var aesgcmCiphers = map[uint16]bool{ - // 1.2 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true, - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true, - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true, - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true, - // 1.3 - TLS_AES_128_GCM_SHA256: true, - TLS_AES_256_GCM_SHA384: true, -} - -var nonAESGCMAEADCiphers = map[uint16]bool{ - // 1.2 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true, - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true, - // 1.3 - TLS_CHACHA20_POLY1305_SHA256: true, -} - -// aesgcmPreferred returns whether the first valid cipher in the preference list -// is an AES-GCM cipher, implying the peer has hardware support for it. -func aesgcmPreferred(ciphers []uint16) bool { - for _, cID := range ciphers { - c := cipherSuiteByID(cID) - if c == nil { - c13 := cipherSuiteTLS13ByID(cID) - if c13 == nil { - continue - } - return aesgcmCiphers[cID] - } - return aesgcmCiphers[cID] - } - return false -} - -// deprioritizeAES reorders cipher preference lists by rearranging -// adjacent AEAD ciphers such that AES-GCM based ciphers are moved -// after other AEAD ciphers. It returns a fresh slice. -func deprioritizeAES(ciphers []uint16) []uint16 { - reordered := make([]uint16, len(ciphers)) - copy(reordered, ciphers) - sort.SliceStable(reordered, func(i, j int) bool { - return nonAESGCMAEADCiphers[reordered[i]] && aesgcmCiphers[reordered[j]] - }) - return reordered -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/common_js.go b/vendor/github.com/marten-seemann/qtls-go1-16/common_js.go deleted file mode 100644 index 97e6ecefd..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/common_js.go +++ /dev/null @@ -1,12 +0,0 @@ -// +build js - -package qtls - -var ( - hasGCMAsmAMD64 = false - hasGCMAsmARM64 = false - // Keep in sync with crypto/aes/cipher_s390x.go. - hasGCMAsmS390X = false - - hasAESGCMHardwareSupport = false -) diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/common_nojs.go b/vendor/github.com/marten-seemann/qtls-go1-16/common_nojs.go deleted file mode 100644 index 5e56e0fb3..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/common_nojs.go +++ /dev/null @@ -1,20 +0,0 @@ -// +build !js - -package qtls - -import ( - "runtime" - - "golang.org/x/sys/cpu" -) - -var ( - hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ - hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL - // Keep in sync with crypto/aes/cipher_s390x.go. - hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) - - hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 || - runtime.GOARCH == "arm64" && hasGCMAsmARM64 || - runtime.GOARCH == "s390x" && hasGCMAsmS390X -) diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/conn.go b/vendor/github.com/marten-seemann/qtls-go1-16/conn.go deleted file mode 100644 index fa5eb3f10..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/conn.go +++ /dev/null @@ -1,1536 +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. - -// TLS low level connection and record layer - -package qtls - -import ( - "bytes" - "crypto/cipher" - "crypto/subtle" - "crypto/x509" - "errors" - "fmt" - "hash" - "io" - "net" - "sync" - "sync/atomic" - "time" -) - -// A Conn represents a secured connection. -// It implements the net.Conn interface. -type Conn struct { - // constant - conn net.Conn - isClient bool - handshakeFn func() error // (*Conn).clientHandshake or serverHandshake - - // handshakeStatus is 1 if the connection is currently transferring - // application data (i.e. is not currently processing a handshake). - // This field is only to be accessed with sync/atomic. - handshakeStatus uint32 - // constant after handshake; protected by handshakeMutex - handshakeMutex sync.Mutex - handshakeErr error // error resulting from handshake - vers uint16 // TLS version - haveVers bool // version has been negotiated - config *config // configuration passed to constructor - // handshakes counts the number of handshakes performed on the - // connection so far. If renegotiation is disabled then this is either - // zero or one. - extraConfig *ExtraConfig - - handshakes int - didResume bool // whether this connection was a session resumption - cipherSuite uint16 - ocspResponse []byte // stapled OCSP response - scts [][]byte // signed certificate timestamps from server - peerCertificates []*x509.Certificate - // verifiedChains contains the certificate chains that we built, as - // opposed to the ones presented by the server. - verifiedChains [][]*x509.Certificate - // serverName contains the server name indicated by the client, if any. - serverName string - // secureRenegotiation is true if the server echoed the secure - // renegotiation extension. (This is meaningless as a server because - // renegotiation is not supported in that case.) - secureRenegotiation bool - // ekm is a closure for exporting keying material. - ekm func(label string, context []byte, length int) ([]byte, error) - // For the client: - // resumptionSecret is the resumption_master_secret for handling - // NewSessionTicket messages. nil if config.SessionTicketsDisabled. - // For the server: - // resumptionSecret is the resumption_master_secret for generating - // NewSessionTicket messages. Only used when the alternative record - // layer is set. nil if config.SessionTicketsDisabled. - resumptionSecret []byte - - // ticketKeys is the set of active session ticket keys for this - // connection. The first one is used to encrypt new tickets and - // all are tried to decrypt tickets. - ticketKeys []ticketKey - - // clientFinishedIsFirst is true if the client sent the first Finished - // message during the most recent handshake. This is recorded because - // the first transmitted Finished message is the tls-unique - // channel-binding value. - clientFinishedIsFirst bool - - // closeNotifyErr is any error from sending the alertCloseNotify record. - closeNotifyErr error - // closeNotifySent is true if the Conn attempted to send an - // alertCloseNotify record. - closeNotifySent bool - - // clientFinished and serverFinished contain the Finished message sent - // by the client or server in the most recent handshake. This is - // retained to support the renegotiation extension and tls-unique - // channel-binding. - clientFinished [12]byte - serverFinished [12]byte - - // clientProtocol is the negotiated ALPN protocol. - clientProtocol string - - // input/output - in, out halfConn - rawInput bytes.Buffer // raw input, starting with a record header - input bytes.Reader // application data waiting to be read, from rawInput.Next - hand bytes.Buffer // handshake data waiting to be read - buffering bool // whether records are buffered in sendBuf - sendBuf []byte // a buffer of records waiting to be sent - - // bytesSent counts the bytes of application data sent. - // packetsSent counts packets. - bytesSent int64 - packetsSent int64 - - // retryCount counts the number of consecutive non-advancing records - // received by Conn.readRecord. That is, records that neither advance the - // handshake, nor deliver application data. Protected by in.Mutex. - retryCount int - - // activeCall is an atomic int32; the low bit is whether Close has - // been called. the rest of the bits are the number of goroutines - // in Conn.Write. - activeCall int32 - - used0RTT bool - - tmp [16]byte -} - -// Access to net.Conn methods. -// Cannot just embed net.Conn because that would -// export the struct field too. - -// LocalAddr returns the local network address. -func (c *Conn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -// RemoteAddr returns the remote network address. -func (c *Conn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -// SetDeadline sets the read and write deadlines associated with the connection. -// A zero value for t means Read and Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -// SetReadDeadline sets the read deadline on the underlying connection. -// A zero value for t means Read will not time out. -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -// SetWriteDeadline sets the write deadline on the underlying connection. -// A zero value for t means Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -// A halfConn represents one direction of the record layer -// connection, either sending or receiving. -type halfConn struct { - sync.Mutex - - err error // first permanent error - version uint16 // protocol version - cipher interface{} // cipher algorithm - mac hash.Hash - seq [8]byte // 64-bit sequence number - - scratchBuf [13]byte // to avoid allocs; interface method args escape - - nextCipher interface{} // next encryption state - nextMac hash.Hash // next MAC algorithm - - trafficSecret []byte // current TLS 1.3 traffic secret - - setKeyCallback func(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte) -} - -type permanentError struct { - err net.Error -} - -func (e *permanentError) Error() string { return e.err.Error() } -func (e *permanentError) Unwrap() error { return e.err } -func (e *permanentError) Timeout() bool { return e.err.Timeout() } -func (e *permanentError) Temporary() bool { return false } - -func (hc *halfConn) setErrorLocked(err error) error { - if e, ok := err.(net.Error); ok { - hc.err = &permanentError{err: e} - } else { - hc.err = err - } - return hc.err -} - -// prepareCipherSpec sets the encryption and MAC states -// that a subsequent changeCipherSpec will use. -func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac hash.Hash) { - hc.version = version - hc.nextCipher = cipher - hc.nextMac = mac -} - -// changeCipherSpec changes the encryption and MAC states -// to the ones previously passed to prepareCipherSpec. -func (hc *halfConn) changeCipherSpec() error { - if hc.nextCipher == nil || hc.version == VersionTLS13 { - return alertInternalError - } - hc.cipher = hc.nextCipher - hc.mac = hc.nextMac - hc.nextCipher = nil - hc.nextMac = nil - for i := range hc.seq { - hc.seq[i] = 0 - } - return nil -} - -func (hc *halfConn) exportKey(encLevel EncryptionLevel, suite *cipherSuiteTLS13, trafficSecret []byte) { - if hc.setKeyCallback != nil { - s := &CipherSuiteTLS13{ - ID: suite.id, - KeyLen: suite.keyLen, - Hash: suite.hash, - AEAD: func(key, fixedNonce []byte) cipher.AEAD { return suite.aead(key, fixedNonce) }, - } - hc.setKeyCallback(encLevel, s, trafficSecret) - } -} - -func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, secret []byte) { - hc.trafficSecret = secret - key, iv := suite.trafficKey(secret) - hc.cipher = suite.aead(key, iv) - for i := range hc.seq { - hc.seq[i] = 0 - } -} - -// incSeq increments the sequence number. -func (hc *halfConn) incSeq() { - for i := 7; i >= 0; i-- { - hc.seq[i]++ - if hc.seq[i] != 0 { - return - } - } - - // Not allowed to let sequence number wrap. - // Instead, must renegotiate before it does. - // Not likely enough to bother. - panic("TLS: sequence number wraparound") -} - -// explicitNonceLen returns the number of bytes of explicit nonce or IV included -// in each record. Explicit nonces are present only in CBC modes after TLS 1.0 -// and in certain AEAD modes in TLS 1.2. -func (hc *halfConn) explicitNonceLen() int { - if hc.cipher == nil { - return 0 - } - - switch c := hc.cipher.(type) { - case cipher.Stream: - return 0 - case aead: - return c.explicitNonceLen() - case cbcMode: - // TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack. - if hc.version >= VersionTLS11 { - return c.BlockSize() - } - return 0 - default: - panic("unknown cipher type") - } -} - -// extractPadding returns, in constant time, the length of the padding to remove -// from the end of payload. It also returns a byte which is equal to 255 if the -// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2. -func extractPadding(payload []byte) (toRemove int, good byte) { - if len(payload) < 1 { - return 0, 0 - } - - paddingLen := payload[len(payload)-1] - t := uint(len(payload)-1) - uint(paddingLen) - // if len(payload) >= (paddingLen - 1) then the MSB of t is zero - good = byte(int32(^t) >> 31) - - // The maximum possible padding length plus the actual length field - toCheck := 256 - // The length of the padded data is public, so we can use an if here - if toCheck > len(payload) { - toCheck = len(payload) - } - - for i := 0; i < toCheck; i++ { - t := uint(paddingLen) - uint(i) - // if i <= paddingLen then the MSB of t is zero - mask := byte(int32(^t) >> 31) - b := payload[len(payload)-1-i] - good &^= mask&paddingLen ^ mask&b - } - - // We AND together the bits of good and replicate the result across - // all the bits. - good &= good << 4 - good &= good << 2 - good &= good << 1 - good = uint8(int8(good) >> 7) - - // Zero the padding length on error. This ensures any unchecked bytes - // are included in the MAC. Otherwise, an attacker that could - // distinguish MAC failures from padding failures could mount an attack - // similar to POODLE in SSL 3.0: given a good ciphertext that uses a - // full block's worth of padding, replace the final block with another - // block. If the MAC check passed but the padding check failed, the - // last byte of that block decrypted to the block size. - // - // See also macAndPaddingGood logic below. - paddingLen &= good - - toRemove = int(paddingLen) + 1 - return -} - -func roundUp(a, b int) int { - return a + (b-a%b)%b -} - -// cbcMode is an interface for block ciphers using cipher block chaining. -type cbcMode interface { - cipher.BlockMode - SetIV([]byte) -} - -// decrypt authenticates and decrypts the record if protection is active at -// this stage. The returned plaintext might overlap with the input. -func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) { - var plaintext []byte - typ := recordType(record[0]) - payload := record[recordHeaderLen:] - - // In TLS 1.3, change_cipher_spec messages are to be ignored without being - // decrypted. See RFC 8446, Appendix D.4. - if hc.version == VersionTLS13 && typ == recordTypeChangeCipherSpec { - return payload, typ, nil - } - - paddingGood := byte(255) - paddingLen := 0 - - explicitNonceLen := hc.explicitNonceLen() - - if hc.cipher != nil { - switch c := hc.cipher.(type) { - case cipher.Stream: - c.XORKeyStream(payload, payload) - case aead: - if len(payload) < explicitNonceLen { - return nil, 0, alertBadRecordMAC - } - nonce := payload[:explicitNonceLen] - if len(nonce) == 0 { - nonce = hc.seq[:] - } - payload = payload[explicitNonceLen:] - - var additionalData []byte - if hc.version == VersionTLS13 { - additionalData = record[:recordHeaderLen] - } else { - additionalData = append(hc.scratchBuf[:0], hc.seq[:]...) - additionalData = append(additionalData, record[:3]...) - n := len(payload) - c.Overhead() - additionalData = append(additionalData, byte(n>>8), byte(n)) - } - - var err error - plaintext, err = c.Open(payload[:0], nonce, payload, additionalData) - if err != nil { - return nil, 0, alertBadRecordMAC - } - case cbcMode: - blockSize := c.BlockSize() - minPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize) - if len(payload)%blockSize != 0 || len(payload) < minPayload { - return nil, 0, alertBadRecordMAC - } - - if explicitNonceLen > 0 { - c.SetIV(payload[:explicitNonceLen]) - payload = payload[explicitNonceLen:] - } - c.CryptBlocks(payload, payload) - - // In a limited attempt to protect against CBC padding oracles like - // Lucky13, the data past paddingLen (which is secret) is passed to - // the MAC function as extra data, to be fed into the HMAC after - // computing the digest. This makes the MAC roughly constant time as - // long as the digest computation is constant time and does not - // affect the subsequent write, modulo cache effects. - paddingLen, paddingGood = extractPadding(payload) - default: - panic("unknown cipher type") - } - - if hc.version == VersionTLS13 { - if typ != recordTypeApplicationData { - return nil, 0, alertUnexpectedMessage - } - if len(plaintext) > maxPlaintext+1 { - return nil, 0, alertRecordOverflow - } - // Remove padding and find the ContentType scanning from the end. - for i := len(plaintext) - 1; i >= 0; i-- { - if plaintext[i] != 0 { - typ = recordType(plaintext[i]) - plaintext = plaintext[:i] - break - } - if i == 0 { - return nil, 0, alertUnexpectedMessage - } - } - } - } else { - plaintext = payload - } - - if hc.mac != nil { - macSize := hc.mac.Size() - if len(payload) < macSize { - return nil, 0, alertBadRecordMAC - } - - n := len(payload) - macSize - paddingLen - n = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 } - record[3] = byte(n >> 8) - record[4] = byte(n) - remoteMAC := payload[n : n+macSize] - localMAC := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload[:n], payload[n+macSize:]) - - // This is equivalent to checking the MACs and paddingGood - // separately, but in constant-time to prevent distinguishing - // padding failures from MAC failures. Depending on what value - // of paddingLen was returned on bad padding, distinguishing - // bad MAC from bad padding can lead to an attack. - // - // See also the logic at the end of extractPadding. - macAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood) - if macAndPaddingGood != 1 { - return nil, 0, alertBadRecordMAC - } - - plaintext = payload[:n] - } - - hc.incSeq() - return plaintext, typ, nil -} - -func (c *Conn) setAlternativeRecordLayer() { - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - c.in.setKeyCallback = c.extraConfig.AlternativeRecordLayer.SetReadKey - c.out.setKeyCallback = c.extraConfig.AlternativeRecordLayer.SetWriteKey - } -} - -// sliceForAppend extends the input slice by n bytes. head is the full extended -// slice, while tail is the appended part. If the original slice has sufficient -// capacity 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 -} - -// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and -// appends it to record, which must already contain the record header. -func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) { - if hc.cipher == nil { - return append(record, payload...), nil - } - - var explicitNonce []byte - if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 { - record, explicitNonce = sliceForAppend(record, explicitNonceLen) - if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 { - // The AES-GCM construction in TLS has an explicit nonce so that the - // nonce can be random. However, the nonce is only 8 bytes which is - // too small for a secure, random nonce. Therefore we use the - // sequence number as the nonce. The 3DES-CBC construction also has - // an 8 bytes nonce but its nonces must be unpredictable (see RFC - // 5246, Appendix F.3), forcing us to use randomness. That's not - // 3DES' biggest problem anyway because the birthday bound on block - // collision is reached first due to its similarly small block size - // (see the Sweet32 attack). - copy(explicitNonce, hc.seq[:]) - } else { - if _, err := io.ReadFull(rand, explicitNonce); err != nil { - return nil, err - } - } - } - - var dst []byte - switch c := hc.cipher.(type) { - case cipher.Stream: - mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil) - record, dst = sliceForAppend(record, len(payload)+len(mac)) - c.XORKeyStream(dst[:len(payload)], payload) - c.XORKeyStream(dst[len(payload):], mac) - case aead: - nonce := explicitNonce - if len(nonce) == 0 { - nonce = hc.seq[:] - } - - if hc.version == VersionTLS13 { - record = append(record, payload...) - - // Encrypt the actual ContentType and replace the plaintext one. - record = append(record, record[0]) - record[0] = byte(recordTypeApplicationData) - - n := len(payload) + 1 + c.Overhead() - record[3] = byte(n >> 8) - record[4] = byte(n) - - record = c.Seal(record[:recordHeaderLen], - nonce, record[recordHeaderLen:], record[:recordHeaderLen]) - } else { - additionalData := append(hc.scratchBuf[:0], hc.seq[:]...) - additionalData = append(additionalData, record[:recordHeaderLen]...) - record = c.Seal(record, nonce, payload, additionalData) - } - case cbcMode: - mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil) - blockSize := c.BlockSize() - plaintextLen := len(payload) + len(mac) - paddingLen := blockSize - plaintextLen%blockSize - record, dst = sliceForAppend(record, plaintextLen+paddingLen) - copy(dst, payload) - copy(dst[len(payload):], mac) - for i := plaintextLen; i < len(dst); i++ { - dst[i] = byte(paddingLen - 1) - } - if len(explicitNonce) > 0 { - c.SetIV(explicitNonce) - } - c.CryptBlocks(dst, dst) - default: - panic("unknown cipher type") - } - - // Update length to include nonce, MAC and any block padding needed. - n := len(record) - recordHeaderLen - record[3] = byte(n >> 8) - record[4] = byte(n) - hc.incSeq() - - return record, nil -} - -// RecordHeaderError is returned when a TLS record header is invalid. -type RecordHeaderError struct { - // Msg contains a human readable string that describes the error. - Msg string - // RecordHeader contains the five bytes of TLS record header that - // triggered the error. - RecordHeader [5]byte - // Conn provides the underlying net.Conn in the case that a client - // sent an initial handshake that didn't look like TLS. - // It is nil if there's already been a handshake or a TLS alert has - // been written to the connection. - Conn net.Conn -} - -func (e RecordHeaderError) Error() string { return "tls: " + e.Msg } - -func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) { - err.Msg = msg - err.Conn = conn - copy(err.RecordHeader[:], c.rawInput.Bytes()) - return err -} - -func (c *Conn) readRecord() error { - return c.readRecordOrCCS(false) -} - -func (c *Conn) readChangeCipherSpec() error { - return c.readRecordOrCCS(true) -} - -// readRecordOrCCS reads one or more TLS records from the connection and -// updates the record layer state. Some invariants: -// * c.in must be locked -// * c.input must be empty -// During the handshake one and only one of the following will happen: -// - c.hand grows -// - c.in.changeCipherSpec is called -// - an error is returned -// After the handshake one and only one of the following will happen: -// - c.hand grows -// - c.input is set -// - an error is returned -func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error { - if c.in.err != nil { - return c.in.err - } - handshakeComplete := c.handshakeComplete() - - // This function modifies c.rawInput, which owns the c.input memory. - if c.input.Len() != 0 { - return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data")) - } - c.input.Reset(nil) - - // Read header, payload. - if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil { - // RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify - // is an error, but popular web sites seem to do this, so we accept it - // if and only if at the record boundary. - if err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 { - err = io.EOF - } - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.in.setErrorLocked(err) - } - return err - } - hdr := c.rawInput.Bytes()[:recordHeaderLen] - typ := recordType(hdr[0]) - - // No valid TLS record has a type of 0x80, however SSLv2 handshakes - // start with a uint16 length where the MSB is set and the first record - // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests - // an SSLv2 client. - if !handshakeComplete && typ == 0x80 { - c.sendAlert(alertProtocolVersion) - return c.in.setErrorLocked(c.newRecordHeaderError(nil, "unsupported SSLv2 handshake received")) - } - - vers := uint16(hdr[1])<<8 | uint16(hdr[2]) - n := int(hdr[3])<<8 | int(hdr[4]) - if c.haveVers && c.vers != VersionTLS13 && vers != c.vers { - c.sendAlert(alertProtocolVersion) - msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, c.vers) - return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg)) - } - if !c.haveVers { - // First message, be extra suspicious: this might not be a TLS - // client. Bail out before reading a full 'body', if possible. - // The current max version is 3.3 so if the version is >= 16.0, - // it's probably not real. - if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 { - return c.in.setErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake")) - } - } - if c.vers == VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext { - c.sendAlert(alertRecordOverflow) - msg := fmt.Sprintf("oversized record received with length %d", n) - return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg)) - } - if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil { - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.in.setErrorLocked(err) - } - return err - } - - // Process message. - record := c.rawInput.Next(recordHeaderLen + n) - data, typ, err := c.in.decrypt(record) - if err != nil { - return c.in.setErrorLocked(c.sendAlert(err.(alert))) - } - if len(data) > maxPlaintext { - return c.in.setErrorLocked(c.sendAlert(alertRecordOverflow)) - } - - // Application Data messages are always protected. - if c.in.cipher == nil && typ == recordTypeApplicationData { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 { - // This is a state-advancing message: reset the retry count. - c.retryCount = 0 - } - - // Handshake messages MUST NOT be interleaved with other record types in TLS 1.3. - if c.vers == VersionTLS13 && typ != recordTypeHandshake && c.hand.Len() > 0 { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - switch typ { - default: - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - - case recordTypeAlert: - if len(data) != 2 { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - if alert(data[1]) == alertCloseNotify { - return c.in.setErrorLocked(io.EOF) - } - if c.vers == VersionTLS13 { - return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])}) - } - switch data[0] { - case alertLevelWarning: - // Drop the record on the floor and retry. - return c.retryReadRecord(expectChangeCipherSpec) - case alertLevelError: - return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])}) - default: - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - case recordTypeChangeCipherSpec: - if len(data) != 1 || data[0] != 1 { - return c.in.setErrorLocked(c.sendAlert(alertDecodeError)) - } - // Handshake messages are not allowed to fragment across the CCS. - if c.hand.Len() > 0 { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - // In TLS 1.3, change_cipher_spec records are ignored until the - // Finished. See RFC 8446, Appendix D.4. Note that according to Section - // 5, a server can send a ChangeCipherSpec before its ServerHello, when - // c.vers is still unset. That's not useful though and suspicious if the - // server then selects a lower protocol version, so don't allow that. - if c.vers == VersionTLS13 { - return c.retryReadRecord(expectChangeCipherSpec) - } - if !expectChangeCipherSpec { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - if err := c.in.changeCipherSpec(); err != nil { - return c.in.setErrorLocked(c.sendAlert(err.(alert))) - } - - case recordTypeApplicationData: - if !handshakeComplete || expectChangeCipherSpec { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - // Some OpenSSL servers send empty records in order to randomize the - // CBC IV. Ignore a limited number of empty records. - if len(data) == 0 { - return c.retryReadRecord(expectChangeCipherSpec) - } - // Note that data is owned by c.rawInput, following the Next call above, - // to avoid copying the plaintext. This is safe because c.rawInput is - // not read from or written to until c.input is drained. - c.input.Reset(data) - - case recordTypeHandshake: - if len(data) == 0 || expectChangeCipherSpec { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - c.hand.Write(data) - } - - return nil -} - -// retryReadRecord recurses into readRecordOrCCS to drop a non-advancing record, like -// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3. -func (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error { - c.retryCount++ - if c.retryCount > maxUselessRecords { - c.sendAlert(alertUnexpectedMessage) - return c.in.setErrorLocked(errors.New("tls: too many ignored records")) - } - return c.readRecordOrCCS(expectChangeCipherSpec) -} - -// atLeastReader reads from R, stopping with EOF once at least N bytes have been -// read. It is different from an io.LimitedReader in that it doesn't cut short -// the last Read call, and in that it considers an early EOF an error. -type atLeastReader struct { - R io.Reader - N int64 -} - -func (r *atLeastReader) Read(p []byte) (int, error) { - if r.N <= 0 { - return 0, io.EOF - } - n, err := r.R.Read(p) - r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809 - if r.N > 0 && err == io.EOF { - return n, io.ErrUnexpectedEOF - } - if r.N <= 0 && err == nil { - return n, io.EOF - } - return n, err -} - -// readFromUntil reads from r into c.rawInput until c.rawInput contains -// at least n bytes or else returns an error. -func (c *Conn) readFromUntil(r io.Reader, n int) error { - if c.rawInput.Len() >= n { - return nil - } - needs := n - c.rawInput.Len() - // There might be extra input waiting on the wire. Make a best effort - // attempt to fetch it so that it can be used in (*Conn).Read to - // "predict" closeNotify alerts. - c.rawInput.Grow(needs + bytes.MinRead) - _, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)}) - return err -} - -// sendAlert sends a TLS alert message. -func (c *Conn) sendAlertLocked(err alert) error { - switch err { - case alertNoRenegotiation, alertCloseNotify: - c.tmp[0] = alertLevelWarning - default: - c.tmp[0] = alertLevelError - } - c.tmp[1] = byte(err) - - _, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2]) - if err == alertCloseNotify { - // closeNotify is a special case in that it isn't an error. - return writeErr - } - - return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err}) -} - -// sendAlert sends a TLS alert message. -func (c *Conn) sendAlert(err alert) error { - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - c.extraConfig.AlternativeRecordLayer.SendAlert(uint8(err)) - return &net.OpError{Op: "local error", Err: err} - } - - c.out.Lock() - defer c.out.Unlock() - return c.sendAlertLocked(err) -} - -const ( - // tcpMSSEstimate is a conservative estimate of the TCP maximum segment - // size (MSS). A constant is used, rather than querying the kernel for - // the actual MSS, to avoid complexity. The value here is the IPv6 - // minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40 - // bytes) and a TCP header with timestamps (32 bytes). - tcpMSSEstimate = 1208 - - // recordSizeBoostThreshold is the number of bytes of application data - // sent after which the TLS record size will be increased to the - // maximum. - recordSizeBoostThreshold = 128 * 1024 -) - -// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the -// next application data record. There is the following trade-off: -// -// - For latency-sensitive applications, such as web browsing, each TLS -// record should fit in one TCP segment. -// - For throughput-sensitive applications, such as large file transfers, -// larger TLS records better amortize framing and encryption overheads. -// -// A simple heuristic that works well in practice is to use small records for -// the first 1MB of data, then use larger records for subsequent data, and -// reset back to smaller records after the connection becomes idle. See "High -// Performance Web Networking", Chapter 4, or: -// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/ -// -// In the interests of simplicity and determinism, this code does not attempt -// to reset the record size once the connection is idle, however. -func (c *Conn) maxPayloadSizeForWrite(typ recordType) int { - if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData { - return maxPlaintext - } - - if c.bytesSent >= recordSizeBoostThreshold { - return maxPlaintext - } - - // Subtract TLS overheads to get the maximum payload size. - payloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen() - if c.out.cipher != nil { - switch ciph := c.out.cipher.(type) { - case cipher.Stream: - payloadBytes -= c.out.mac.Size() - case cipher.AEAD: - payloadBytes -= ciph.Overhead() - case cbcMode: - blockSize := ciph.BlockSize() - // The payload must fit in a multiple of blockSize, with - // room for at least one padding byte. - payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1 - // The MAC is appended before padding so affects the - // payload size directly. - payloadBytes -= c.out.mac.Size() - default: - panic("unknown cipher type") - } - } - if c.vers == VersionTLS13 { - payloadBytes-- // encrypted ContentType - } - - // Allow packet growth in arithmetic progression up to max. - pkt := c.packetsSent - c.packetsSent++ - if pkt > 1000 { - return maxPlaintext // avoid overflow in multiply below - } - - n := payloadBytes * int(pkt+1) - if n > maxPlaintext { - n = maxPlaintext - } - return n -} - -func (c *Conn) write(data []byte) (int, error) { - if c.buffering { - c.sendBuf = append(c.sendBuf, data...) - return len(data), nil - } - - n, err := c.conn.Write(data) - c.bytesSent += int64(n) - return n, err -} - -func (c *Conn) flush() (int, error) { - if len(c.sendBuf) == 0 { - return 0, nil - } - - n, err := c.conn.Write(c.sendBuf) - c.bytesSent += int64(n) - c.sendBuf = nil - c.buffering = false - return n, err -} - -// outBufPool pools the record-sized scratch buffers used by writeRecordLocked. -var outBufPool = sync.Pool{ - New: func() interface{} { - return new([]byte) - }, -} - -// writeRecordLocked writes a TLS record with the given type and payload to the -// connection and updates the record layer state. -func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { - outBufPtr := outBufPool.Get().(*[]byte) - outBuf := *outBufPtr - defer func() { - // You might be tempted to simplify this by just passing &outBuf to Put, - // but that would make the local copy of the outBuf slice header escape - // to the heap, causing an allocation. Instead, we keep around the - // pointer to the slice header returned by Get, which is already on the - // heap, and overwrite and return that. - *outBufPtr = outBuf - outBufPool.Put(outBufPtr) - }() - - var n int - for len(data) > 0 { - m := len(data) - if maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload { - m = maxPayload - } - - _, outBuf = sliceForAppend(outBuf[:0], recordHeaderLen) - outBuf[0] = byte(typ) - vers := c.vers - if vers == 0 { - // Some TLS servers fail if the record version is - // greater than TLS 1.0 for the initial ClientHello. - vers = VersionTLS10 - } else if vers == VersionTLS13 { - // TLS 1.3 froze the record layer version to 1.2. - // See RFC 8446, Section 5.1. - vers = VersionTLS12 - } - outBuf[1] = byte(vers >> 8) - outBuf[2] = byte(vers) - outBuf[3] = byte(m >> 8) - outBuf[4] = byte(m) - - var err error - outBuf, err = c.out.encrypt(outBuf, data[:m], c.config.rand()) - if err != nil { - return n, err - } - if _, err := c.write(outBuf); err != nil { - return n, err - } - n += m - data = data[m:] - } - - if typ == recordTypeChangeCipherSpec && c.vers != VersionTLS13 { - if err := c.out.changeCipherSpec(); err != nil { - return n, c.sendAlertLocked(err.(alert)) - } - } - - return n, nil -} - -// writeRecord writes a TLS record with the given type and payload to the -// connection and updates the record layer state. -func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) { - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - if typ == recordTypeChangeCipherSpec { - return len(data), nil - } - return c.extraConfig.AlternativeRecordLayer.WriteRecord(data) - } - - c.out.Lock() - defer c.out.Unlock() - - return c.writeRecordLocked(typ, data) -} - -// readHandshake reads the next handshake message from -// the record layer. -func (c *Conn) readHandshake() (interface{}, error) { - var data []byte - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - var err error - data, err = c.extraConfig.AlternativeRecordLayer.ReadHandshakeMessage() - if err != nil { - return nil, err - } - } else { - for c.hand.Len() < 4 { - if err := c.readRecord(); err != nil { - return nil, err - } - } - - data = c.hand.Bytes() - n := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if n > maxHandshake { - c.sendAlertLocked(alertInternalError) - return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)) - } - for c.hand.Len() < 4+n { - if err := c.readRecord(); err != nil { - return nil, err - } - } - data = c.hand.Next(4 + n) - } - var m handshakeMessage - switch data[0] { - case typeHelloRequest: - m = new(helloRequestMsg) - case typeClientHello: - m = new(clientHelloMsg) - case typeServerHello: - m = new(serverHelloMsg) - case typeNewSessionTicket: - if c.vers == VersionTLS13 { - m = new(newSessionTicketMsgTLS13) - } else { - m = new(newSessionTicketMsg) - } - case typeCertificate: - if c.vers == VersionTLS13 { - m = new(certificateMsgTLS13) - } else { - m = new(certificateMsg) - } - case typeCertificateRequest: - if c.vers == VersionTLS13 { - m = new(certificateRequestMsgTLS13) - } else { - m = &certificateRequestMsg{ - hasSignatureAlgorithm: c.vers >= VersionTLS12, - } - } - case typeCertificateStatus: - m = new(certificateStatusMsg) - case typeServerKeyExchange: - m = new(serverKeyExchangeMsg) - case typeServerHelloDone: - m = new(serverHelloDoneMsg) - case typeClientKeyExchange: - m = new(clientKeyExchangeMsg) - case typeCertificateVerify: - m = &certificateVerifyMsg{ - hasSignatureAlgorithm: c.vers >= VersionTLS12, - } - case typeFinished: - m = new(finishedMsg) - case typeEncryptedExtensions: - m = new(encryptedExtensionsMsg) - case typeEndOfEarlyData: - m = new(endOfEarlyDataMsg) - case typeKeyUpdate: - m = new(keyUpdateMsg) - default: - return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - // The handshake message unmarshalers - // expect to be able to keep references to data, - // so pass in a fresh copy that won't be overwritten. - data = append([]byte(nil), data...) - - if !m.unmarshal(data) { - return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - return m, nil -} - -var ( - errShutdown = errors.New("tls: protocol is shutdown") -) - -// Write writes data to the connection. -// -// As Write calls Handshake, in order to prevent indefinite blocking a deadline -// must be set for both Read and Write before Write is called when the handshake -// has not yet completed. See SetDeadline, SetReadDeadline, and -// SetWriteDeadline. -func (c *Conn) Write(b []byte) (int, error) { - // interlock with Close below - for { - x := atomic.LoadInt32(&c.activeCall) - if x&1 != 0 { - return 0, net.ErrClosed - } - if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) { - break - } - } - defer atomic.AddInt32(&c.activeCall, -2) - - if err := c.Handshake(); err != nil { - return 0, err - } - - c.out.Lock() - defer c.out.Unlock() - - if err := c.out.err; err != nil { - return 0, err - } - - if !c.handshakeComplete() { - return 0, alertInternalError - } - - if c.closeNotifySent { - return 0, errShutdown - } - - // TLS 1.0 is susceptible to a chosen-plaintext - // attack when using block mode ciphers due to predictable IVs. - // This can be prevented by splitting each Application Data - // record into two records, effectively randomizing the IV. - // - // https://www.openssl.org/~bodo/tls-cbc.txt - // https://bugzilla.mozilla.org/show_bug.cgi?id=665814 - // https://www.imperialviolet.org/2012/01/15/beastfollowup.html - - var m int - if len(b) > 1 && c.vers == VersionTLS10 { - if _, ok := c.out.cipher.(cipher.BlockMode); ok { - n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1]) - if err != nil { - return n, c.out.setErrorLocked(err) - } - m, b = 1, b[1:] - } - } - - n, err := c.writeRecordLocked(recordTypeApplicationData, b) - return n + m, c.out.setErrorLocked(err) -} - -// handleRenegotiation processes a HelloRequest handshake message. -func (c *Conn) handleRenegotiation() error { - if c.vers == VersionTLS13 { - return errors.New("tls: internal error: unexpected renegotiation") - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - helloReq, ok := msg.(*helloRequestMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(helloReq, msg) - } - - if !c.isClient { - return c.sendAlert(alertNoRenegotiation) - } - - switch c.config.Renegotiation { - case RenegotiateNever: - return c.sendAlert(alertNoRenegotiation) - case RenegotiateOnceAsClient: - if c.handshakes > 1 { - return c.sendAlert(alertNoRenegotiation) - } - case RenegotiateFreelyAsClient: - // Ok. - default: - c.sendAlert(alertInternalError) - return errors.New("tls: unknown Renegotiation value") - } - - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - atomic.StoreUint32(&c.handshakeStatus, 0) - if c.handshakeErr = c.clientHandshake(); c.handshakeErr == nil { - c.handshakes++ - } - return c.handshakeErr -} - -func (c *Conn) HandlePostHandshakeMessage() error { - return c.handlePostHandshakeMessage() -} - -// handlePostHandshakeMessage processes a handshake message arrived after the -// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation. -func (c *Conn) handlePostHandshakeMessage() error { - if c.vers != VersionTLS13 { - return c.handleRenegotiation() - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - c.retryCount++ - if c.retryCount > maxUselessRecords { - c.sendAlert(alertUnexpectedMessage) - return c.in.setErrorLocked(errors.New("tls: too many non-advancing records")) - } - - switch msg := msg.(type) { - case *newSessionTicketMsgTLS13: - return c.handleNewSessionTicket(msg) - case *keyUpdateMsg: - return c.handleKeyUpdate(msg) - default: - c.sendAlert(alertUnexpectedMessage) - return fmt.Errorf("tls: received unexpected handshake message of type %T", msg) - } -} - -func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error { - cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) - if cipherSuite == nil { - return c.in.setErrorLocked(c.sendAlert(alertInternalError)) - } - - newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret) - c.in.setTrafficSecret(cipherSuite, newSecret) - - if keyUpdate.updateRequested { - c.out.Lock() - defer c.out.Unlock() - - msg := &keyUpdateMsg{} - _, err := c.writeRecordLocked(recordTypeHandshake, msg.marshal()) - if err != nil { - // Surface the error at the next write. - c.out.setErrorLocked(err) - return nil - } - - newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret) - c.out.setTrafficSecret(cipherSuite, newSecret) - } - - return nil -} - -// Read reads data from the connection. -// -// As Read calls Handshake, in order to prevent indefinite blocking a deadline -// must be set for both Read and Write before Read is called when the handshake -// has not yet completed. See SetDeadline, SetReadDeadline, and -// SetWriteDeadline. -func (c *Conn) Read(b []byte) (int, error) { - if err := c.Handshake(); err != nil { - return 0, err - } - if len(b) == 0 { - // Put this after Handshake, in case people were calling - // Read(nil) for the side effect of the Handshake. - return 0, nil - } - - c.in.Lock() - defer c.in.Unlock() - - for c.input.Len() == 0 { - if err := c.readRecord(); err != nil { - return 0, err - } - for c.hand.Len() > 0 { - if err := c.handlePostHandshakeMessage(); err != nil { - return 0, err - } - } - } - - n, _ := c.input.Read(b) - - // If a close-notify alert is waiting, read it so that we can return (n, - // EOF) instead of (n, nil), to signal to the HTTP response reading - // goroutine that the connection is now closed. This eliminates a race - // where the HTTP response reading goroutine would otherwise not observe - // the EOF until its next read, by which time a client goroutine might - // have already tried to reuse the HTTP connection for a new request. - // See https://golang.org/cl/76400046 and https://golang.org/issue/3514 - if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 && - recordType(c.rawInput.Bytes()[0]) == recordTypeAlert { - if err := c.readRecord(); err != nil { - return n, err // will be io.EOF on closeNotify - } - } - - return n, nil -} - -// Close closes the connection. -func (c *Conn) Close() error { - // Interlock with Conn.Write above. - var x int32 - for { - x = atomic.LoadInt32(&c.activeCall) - if x&1 != 0 { - return net.ErrClosed - } - if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) { - break - } - } - if x != 0 { - // io.Writer and io.Closer should not be used concurrently. - // If Close is called while a Write is currently in-flight, - // interpret that as a sign that this Close is really just - // being used to break the Write and/or clean up resources and - // avoid sending the alertCloseNotify, which may block - // waiting on handshakeMutex or the c.out mutex. - return c.conn.Close() - } - - var alertErr error - if c.handshakeComplete() { - if err := c.closeNotify(); err != nil { - alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err) - } - } - - if err := c.conn.Close(); err != nil { - return err - } - return alertErr -} - -var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete") - -// CloseWrite shuts down the writing side of the connection. It should only be -// called once the handshake has completed and does not call CloseWrite on the -// underlying connection. Most callers should just use Close. -func (c *Conn) CloseWrite() error { - if !c.handshakeComplete() { - return errEarlyCloseWrite - } - - return c.closeNotify() -} - -func (c *Conn) closeNotify() error { - c.out.Lock() - defer c.out.Unlock() - - if !c.closeNotifySent { - // Set a Write Deadline to prevent possibly blocking forever. - c.SetWriteDeadline(time.Now().Add(time.Second * 5)) - c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify) - c.closeNotifySent = true - // Any subsequent writes will fail. - c.SetWriteDeadline(time.Now()) - } - return c.closeNotifyErr -} - -// Handshake runs the client or server handshake -// protocol if it has not yet been run. -// -// Most uses of this package need not call Handshake explicitly: the -// first Read or Write will call it automatically. -// -// For control over canceling or setting a timeout on a handshake, use -// the Dialer's DialContext method. -func (c *Conn) Handshake() error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - if err := c.handshakeErr; err != nil { - return err - } - if c.handshakeComplete() { - return nil - } - - c.in.Lock() - defer c.in.Unlock() - - c.handshakeErr = c.handshakeFn() - if c.handshakeErr == nil { - c.handshakes++ - } else { - // If an error occurred during the handshake try to flush the - // alert that might be left in the buffer. - c.flush() - } - - if c.handshakeErr == nil && !c.handshakeComplete() { - c.handshakeErr = errors.New("tls: internal error: handshake should have had a result") - } - - return c.handshakeErr -} - -// ConnectionState returns basic TLS details about the connection. -func (c *Conn) ConnectionState() ConnectionState { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - return c.connectionStateLocked() -} - -// ConnectionStateWith0RTT returns basic TLS details (incl. 0-RTT status) about the connection. -func (c *Conn) ConnectionStateWith0RTT() ConnectionStateWith0RTT { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - return ConnectionStateWith0RTT{ - ConnectionState: c.connectionStateLocked(), - Used0RTT: c.used0RTT, - } -} - -func (c *Conn) connectionStateLocked() ConnectionState { - var state connectionState - state.HandshakeComplete = c.handshakeComplete() - state.Version = c.vers - state.NegotiatedProtocol = c.clientProtocol - state.DidResume = c.didResume - state.NegotiatedProtocolIsMutual = true - state.ServerName = c.serverName - state.CipherSuite = c.cipherSuite - state.PeerCertificates = c.peerCertificates - state.VerifiedChains = c.verifiedChains - state.SignedCertificateTimestamps = c.scts - state.OCSPResponse = c.ocspResponse - if !c.didResume && c.vers != VersionTLS13 { - if c.clientFinishedIsFirst { - state.TLSUnique = c.clientFinished[:] - } else { - state.TLSUnique = c.serverFinished[:] - } - } - if c.config.Renegotiation != RenegotiateNever { - state.ekm = noExportedKeyingMaterial - } else { - state.ekm = c.ekm - } - return toConnectionState(state) -} - -// OCSPResponse returns the stapled OCSP response from the TLS server, if -// any. (Only valid for client connections.) -func (c *Conn) OCSPResponse() []byte { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - return c.ocspResponse -} - -// VerifyHostname checks that the peer certificate chain is valid for -// connecting to host. If so, it returns nil; if not, it returns an error -// describing the problem. -func (c *Conn) VerifyHostname(host string) error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if !c.isClient { - return errors.New("tls: VerifyHostname called on TLS server connection") - } - if !c.handshakeComplete() { - return errors.New("tls: handshake has not yet been performed") - } - if len(c.verifiedChains) == 0 { - return errors.New("tls: handshake did not verify certificate chain") - } - return c.peerCertificates[0].VerifyHostname(host) -} - -func (c *Conn) handshakeComplete() bool { - return atomic.LoadUint32(&c.handshakeStatus) == 1 -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_client.go b/vendor/github.com/marten-seemann/qtls-go1-16/handshake_client.go deleted file mode 100644 index a447061ae..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_client.go +++ /dev/null @@ -1,1105 +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 qtls - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "errors" - "fmt" - "hash" - "io" - "net" - "strings" - "sync/atomic" - "time" - - "golang.org/x/crypto/cryptobyte" -) - -const clientSessionStateVersion = 1 - -type clientHandshakeState struct { - c *Conn - serverHello *serverHelloMsg - hello *clientHelloMsg - suite *cipherSuite - finishedHash finishedHash - masterSecret []byte - session *clientSessionState -} - -func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { - config := c.config - if len(config.ServerName) == 0 && !config.InsecureSkipVerify { - return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config") - } - - nextProtosLength := 0 - for _, proto := range config.NextProtos { - if l := len(proto); l == 0 || l > 255 { - return nil, nil, errors.New("tls: invalid NextProtos value") - } else { - nextProtosLength += 1 + l - } - } - if nextProtosLength > 0xffff { - return nil, nil, errors.New("tls: NextProtos values too large") - } - - var supportedVersions []uint16 - var clientHelloVersion uint16 - if c.extraConfig.usesAlternativeRecordLayer() { - if config.maxSupportedVersion() < VersionTLS13 { - return nil, nil, errors.New("tls: MaxVersion prevents QUIC from using TLS 1.3") - } - // Only offer TLS 1.3 when QUIC is used. - supportedVersions = []uint16{VersionTLS13} - clientHelloVersion = VersionTLS13 - } else { - supportedVersions = config.supportedVersions() - if len(supportedVersions) == 0 { - return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion") - } - clientHelloVersion = config.maxSupportedVersion() - } - - // The version at the beginning of the ClientHello was capped at TLS 1.2 - // for compatibility reasons. The supported_versions extension is used - // to negotiate versions now. See RFC 8446, Section 4.2.1. - if clientHelloVersion > VersionTLS12 { - clientHelloVersion = VersionTLS12 - } - - hello := &clientHelloMsg{ - vers: clientHelloVersion, - compressionMethods: []uint8{compressionNone}, - random: make([]byte, 32), - ocspStapling: true, - scts: true, - serverName: hostnameInSNI(config.ServerName), - supportedCurves: config.curvePreferences(), - supportedPoints: []uint8{pointFormatUncompressed}, - secureRenegotiationSupported: true, - alpnProtocols: config.NextProtos, - supportedVersions: supportedVersions, - } - - if c.handshakes > 0 { - hello.secureRenegotiation = c.clientFinished[:] - } - - possibleCipherSuites := config.cipherSuites() - hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) - - // add non-TLS 1.3 cipher suites - if c.config.MinVersion <= VersionTLS12 { - for _, suiteId := range possibleCipherSuites { - for _, suite := range cipherSuites { - if suite.id != suiteId { - continue - } - // Don't advertise TLS 1.2-only cipher suites unless - // we're attempting TLS 1.2. - if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { - break - } - hello.cipherSuites = append(hello.cipherSuites, suiteId) - break - } - } - } - - _, err := io.ReadFull(config.rand(), hello.random) - if err != nil { - return nil, nil, errors.New("tls: short read from Rand: " + err.Error()) - } - - // A random session ID is used to detect when the server accepted a ticket - // and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as - // a compatibility measure (see RFC 8446, Section 4.1.2). - if c.extraConfig == nil || c.extraConfig.AlternativeRecordLayer == nil { - hello.sessionId = make([]byte, 32) - if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil { - return nil, nil, errors.New("tls: short read from Rand: " + err.Error()) - } - } - - if hello.vers >= VersionTLS12 { - hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms - } - - var params ecdheParameters - if hello.supportedVersions[0] == VersionTLS13 { - var hasTLS13CipherSuite bool - // add TLS 1.3 cipher suites - for _, suiteID := range possibleCipherSuites { - for _, suite := range cipherSuitesTLS13 { - if suite.id == suiteID { - hasTLS13CipherSuite = true - hello.cipherSuites = append(hello.cipherSuites, suiteID) - } - } - } - if !hasTLS13CipherSuite { - hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13()...) - } - - curveID := config.curvePreferences()[0] - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve") - } - params, err = generateECDHEParameters(config.rand(), curveID) - if err != nil { - return nil, nil, err - } - hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} - } - - if hello.supportedVersions[0] == VersionTLS13 && c.extraConfig != nil && c.extraConfig.GetExtensions != nil { - hello.additionalExtensions = c.extraConfig.GetExtensions(typeClientHello) - } - - return hello, params, nil -} - -func (c *Conn) clientHandshake() (err error) { - if c.config == nil { - c.config = fromConfig(defaultConfig()) - } - c.setAlternativeRecordLayer() - - // This may be a renegotiation handshake, in which case some fields - // need to be reset. - c.didResume = false - - hello, ecdheParams, err := c.makeClientHello() - if err != nil { - return err - } - c.serverName = hello.serverName - - cacheKey, session, earlySecret, binderKey := c.loadSession(hello) - if cacheKey != "" && session != nil { - var deletedTicket bool - if session.vers == VersionTLS13 && hello.earlyData && c.extraConfig != nil && c.extraConfig.Enable0RTT { - // don't reuse a session ticket that enabled 0-RTT - c.config.ClientSessionCache.Put(cacheKey, nil) - deletedTicket = true - - if suite := cipherSuiteTLS13ByID(session.cipherSuite); suite != nil { - h := suite.hash.New() - h.Write(hello.marshal()) - clientEarlySecret := suite.deriveSecret(earlySecret, "c e traffic", h) - c.out.exportKey(Encryption0RTT, suite, clientEarlySecret) - if err := c.config.writeKeyLog(keyLogLabelEarlyTraffic, hello.random, clientEarlySecret); err != nil { - c.sendAlert(alertInternalError) - return err - } - } - } - if !deletedTicket { - defer func() { - // If we got a handshake failure when resuming a session, throw away - // the session ticket. See RFC 5077, Section 3.2. - // - // RFC 8446 makes no mention of dropping tickets on failure, but it - // does require servers to abort on invalid binders, so we need to - // delete tickets to recover from a corrupted PSK. - if err != nil { - c.config.ClientSessionCache.Put(cacheKey, nil) - } - }() - } - } - - if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - serverHello, ok := msg.(*serverHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(serverHello, msg) - } - - if err := c.pickTLSVersion(serverHello); err != nil { - return err - } - - // If we are negotiating a protocol version that's lower than what we - // support, check for the server downgrade canaries. - // See RFC 8446, Section 4.1.3. - maxVers := c.config.maxSupportedVersion() - tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12 - tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11 - if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) || - maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox") - } - - if c.vers == VersionTLS13 { - hs := &clientHandshakeStateTLS13{ - c: c, - serverHello: serverHello, - hello: hello, - ecdheParams: ecdheParams, - session: session, - earlySecret: earlySecret, - binderKey: binderKey, - } - - // In TLS 1.3, session tickets are delivered after the handshake. - return hs.handshake() - } - - hs := &clientHandshakeState{ - c: c, - serverHello: serverHello, - hello: hello, - session: session, - } - - if err := hs.handshake(); err != nil { - return err - } - - // If we had a successful handshake and hs.session is different from - // the one already cached - cache a new one. - if cacheKey != "" && hs.session != nil && session != hs.session { - c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(hs.session)) - } - - return nil -} - -// extract the app data saved in the session.nonce, -// and set the session.nonce to the actual nonce value -func (c *Conn) decodeSessionState(session *clientSessionState) (uint32 /* max early data */, []byte /* app data */, bool /* ok */) { - s := cryptobyte.String(session.nonce) - var version uint16 - if !s.ReadUint16(&version) { - return 0, nil, false - } - if version != clientSessionStateVersion { - return 0, nil, false - } - var maxEarlyData uint32 - if !s.ReadUint32(&maxEarlyData) { - return 0, nil, false - } - var appData []byte - if !readUint16LengthPrefixed(&s, &appData) { - return 0, nil, false - } - var nonce []byte - if !readUint16LengthPrefixed(&s, &nonce) { - return 0, nil, false - } - session.nonce = nonce - return maxEarlyData, appData, true -} - -func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string, - session *clientSessionState, earlySecret, binderKey []byte) { - if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { - return "", nil, nil, nil - } - - hello.ticketSupported = true - - if hello.supportedVersions[0] == VersionTLS13 { - // Require DHE on resumption as it guarantees forward secrecy against - // compromise of the session ticket key. See RFC 8446, Section 4.2.9. - hello.pskModes = []uint8{pskModeDHE} - } - - // Session resumption is not allowed if renegotiating because - // renegotiation is primarily used to allow a client to send a client - // certificate, which would be skipped if session resumption occurred. - if c.handshakes != 0 { - return "", nil, nil, nil - } - - // Try to resume a previously negotiated TLS session, if available. - cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config) - sess, ok := c.config.ClientSessionCache.Get(cacheKey) - if !ok || sess == nil { - return cacheKey, nil, nil, nil - } - session = fromClientSessionState(sess) - - var appData []byte - var maxEarlyData uint32 - if session.vers == VersionTLS13 { - var ok bool - maxEarlyData, appData, ok = c.decodeSessionState(session) - if !ok { // delete it, if parsing failed - c.config.ClientSessionCache.Put(cacheKey, nil) - return cacheKey, nil, nil, nil - } - } - - // Check that version used for the previous session is still valid. - versOk := false - for _, v := range hello.supportedVersions { - if v == session.vers { - versOk = true - break - } - } - if !versOk { - return cacheKey, nil, nil, nil - } - - // Check that the cached server certificate is not expired, and that it's - // valid for the ServerName. This should be ensured by the cache key, but - // protect the application from a faulty ClientSessionCache implementation. - if !c.config.InsecureSkipVerify { - if len(session.verifiedChains) == 0 { - // The original connection had InsecureSkipVerify, while this doesn't. - return cacheKey, nil, nil, nil - } - serverCert := session.serverCertificates[0] - if c.config.time().After(serverCert.NotAfter) { - // Expired certificate, delete the entry. - c.config.ClientSessionCache.Put(cacheKey, nil) - return cacheKey, nil, nil, nil - } - if err := serverCert.VerifyHostname(c.config.ServerName); err != nil { - return cacheKey, nil, nil, nil - } - } - - if session.vers != VersionTLS13 { - // In TLS 1.2 the cipher suite must match the resumed session. Ensure we - // are still offering it. - if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil { - return cacheKey, nil, nil, nil - } - - hello.sessionTicket = session.sessionTicket - return - } - - // Check that the session ticket is not expired. - if c.config.time().After(session.useBy) { - c.config.ClientSessionCache.Put(cacheKey, nil) - return cacheKey, nil, nil, nil - } - - // In TLS 1.3 the KDF hash must match the resumed session. Ensure we - // offer at least one cipher suite with that hash. - cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite) - if cipherSuite == nil { - return cacheKey, nil, nil, nil - } - cipherSuiteOk := false - for _, offeredID := range hello.cipherSuites { - offeredSuite := cipherSuiteTLS13ByID(offeredID) - if offeredSuite != nil && offeredSuite.hash == cipherSuite.hash { - cipherSuiteOk = true - break - } - } - if !cipherSuiteOk { - return cacheKey, nil, nil, nil - } - - // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1. - ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond) - identity := pskIdentity{ - label: session.sessionTicket, - obfuscatedTicketAge: ticketAge + session.ageAdd, - } - hello.pskIdentities = []pskIdentity{identity} - hello.pskBinders = [][]byte{make([]byte, cipherSuite.hash.Size())} - - // Compute the PSK binders. See RFC 8446, Section 4.2.11.2. - psk := cipherSuite.expandLabel(session.masterSecret, "resumption", - session.nonce, cipherSuite.hash.Size()) - earlySecret = cipherSuite.extract(psk, nil) - binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil) - if c.extraConfig != nil { - hello.earlyData = c.extraConfig.Enable0RTT && maxEarlyData > 0 - } - transcript := cipherSuite.hash.New() - transcript.Write(hello.marshalWithoutBinders()) - pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)} - hello.updateBinders(pskBinders) - - if session.vers == VersionTLS13 && c.extraConfig != nil && c.extraConfig.SetAppDataFromSessionState != nil { - c.extraConfig.SetAppDataFromSessionState(appData) - } - return -} - -func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error { - peerVersion := serverHello.vers - if serverHello.supportedVersion != 0 { - peerVersion = serverHello.supportedVersion - } - - vers, ok := c.config.mutualVersion([]uint16{peerVersion}) - if !ok { - c.sendAlert(alertProtocolVersion) - return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion) - } - - c.vers = vers - c.haveVers = true - c.in.version = vers - c.out.version = vers - - return nil -} - -// Does the handshake, either a full one or resumes old session. Requires hs.c, -// hs.hello, hs.serverHello, and, optionally, hs.session to be set. -func (hs *clientHandshakeState) handshake() error { - c := hs.c - - isResume, err := hs.processServerHello() - if err != nil { - return err - } - - hs.finishedHash = newFinishedHash(c.vers, hs.suite) - - // No signatures of the handshake are needed in a resumption. - // Otherwise, in a full handshake, if we don't have any certificates - // configured then we will never send a CertificateVerify message and - // thus no signatures are needed in that case either. - if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) { - hs.finishedHash.discardHandshakeBuffer() - } - - hs.finishedHash.Write(hs.hello.marshal()) - hs.finishedHash.Write(hs.serverHello.marshal()) - - c.buffering = true - c.didResume = isResume - if isResume { - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.readSessionTicket(); err != nil { - return err - } - if err := hs.readFinished(c.serverFinished[:]); err != nil { - return err - } - c.clientFinishedIsFirst = false - // Make sure the connection is still being verified whether or not this - // is a resumption. Resumptions currently don't reverify certificates so - // they don't call verifyServerCertificate. See Issue 31641. - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - if err := hs.sendFinished(c.clientFinished[:]); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - } else { - if err := hs.doFullHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.sendFinished(c.clientFinished[:]); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - c.clientFinishedIsFirst = true - if err := hs.readSessionTicket(); err != nil { - return err - } - if err := hs.readFinished(c.serverFinished[:]); err != nil { - return err - } - } - - c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random) - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -func (hs *clientHandshakeState) pickCipherSuite() error { - if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil { - hs.c.sendAlert(alertHandshakeFailure) - return errors.New("tls: server chose an unconfigured cipher suite") - } - - hs.c.cipherSuite = hs.suite.id - return nil -} - -func (hs *clientHandshakeState) doFullHandshake() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - certMsg, ok := msg.(*certificateMsg) - if !ok || len(certMsg.certificates) == 0 { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - hs.finishedHash.Write(certMsg.marshal()) - - msg, err = c.readHandshake() - if err != nil { - return err - } - - cs, ok := msg.(*certificateStatusMsg) - if ok { - // RFC4366 on Certificate Status Request: - // The server MAY return a "certificate_status" message. - - if !hs.serverHello.ocspStapling { - // If a server returns a "CertificateStatus" message, then the - // server MUST have included an extension of type "status_request" - // with empty "extension_data" in the extended server hello. - - c.sendAlert(alertUnexpectedMessage) - return errors.New("tls: received unexpected CertificateStatus message") - } - hs.finishedHash.Write(cs.marshal()) - - c.ocspResponse = cs.response - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - if c.handshakes == 0 { - // If this is the first handshake on a connection, process and - // (optionally) verify the server's certificates. - if err := c.verifyServerCertificate(certMsg.certificates); err != nil { - return err - } - } else { - // This is a renegotiation handshake. We require that the - // server's identity (i.e. leaf certificate) is unchanged and - // thus any previous trust decision is still valid. - // - // See https://mitls.org/pages/attacks/3SHAKE for the - // motivation behind this requirement. - if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) { - c.sendAlert(alertBadCertificate) - return errors.New("tls: server's identity changed during renegotiation") - } - } - - keyAgreement := hs.suite.ka(c.vers) - - skx, ok := msg.(*serverKeyExchangeMsg) - if ok { - hs.finishedHash.Write(skx.marshal()) - err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx) - if err != nil { - c.sendAlert(alertUnexpectedMessage) - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - var chainToSend *Certificate - var certRequested bool - certReq, ok := msg.(*certificateRequestMsg) - if ok { - certRequested = true - hs.finishedHash.Write(certReq.marshal()) - - cri := certificateRequestInfoFromMsg(c.vers, certReq) - if chainToSend, err = c.getClientCertificate(cri); err != nil { - c.sendAlert(alertInternalError) - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - shd, ok := msg.(*serverHelloDoneMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(shd, msg) - } - hs.finishedHash.Write(shd.marshal()) - - // If the server requested a certificate then we have to send a - // Certificate message, even if it's empty because we don't have a - // certificate to send. - if certRequested { - certMsg = new(certificateMsg) - certMsg.certificates = chainToSend.Certificate - hs.finishedHash.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - } - - preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0]) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - if ckx != nil { - hs.finishedHash.Write(ckx.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil { - return err - } - } - - if chainToSend != nil && len(chainToSend.Certificate) > 0 { - certVerify := &certificateVerifyMsg{} - - key, ok := chainToSend.PrivateKey.(crypto.Signer) - if !ok { - c.sendAlert(alertInternalError) - return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey) - } - - var sigType uint8 - var sigHash crypto.Hash - if c.vers >= VersionTLS12 { - signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms) - if err != nil { - c.sendAlert(alertIllegalParameter) - return err - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - certVerify.hasSignatureAlgorithm = true - certVerify.signatureAlgorithm = signatureAlgorithm - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public()) - if err != nil { - c.sendAlert(alertIllegalParameter) - return err - } - } - - signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret) - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - hs.finishedHash.Write(certVerify.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil { - return err - } - } - - hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random) - if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to write to key log: " + err.Error()) - } - - hs.finishedHash.discardHandshakeBuffer() - - return nil -} - -func (hs *clientHandshakeState) establishKeys() error { - c := hs.c - - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) - var clientCipher, serverCipher interface{} - var clientHash, serverHash hash.Hash - if hs.suite.cipher != nil { - clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) - clientHash = hs.suite.mac(clientMAC) - serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) - serverHash = hs.suite.mac(serverMAC) - } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) - } - - c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) - c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) - return nil -} - -func (hs *clientHandshakeState) serverResumedSession() bool { - // If the server responded with the same sessionId then it means the - // sessionTicket is being used to resume a TLS session. - return hs.session != nil && hs.hello.sessionId != nil && - bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId) -} - -func (hs *clientHandshakeState) processServerHello() (bool, error) { - c := hs.c - - if err := hs.pickCipherSuite(); err != nil { - return false, err - } - - if hs.serverHello.compressionMethod != compressionNone { - c.sendAlert(alertUnexpectedMessage) - return false, errors.New("tls: server selected unsupported compression format") - } - - if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported { - c.secureRenegotiation = true - if len(hs.serverHello.secureRenegotiation) != 0 { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: initial handshake had non-empty renegotiation extension") - } - } - - if c.handshakes > 0 && c.secureRenegotiation { - var expectedSecureRenegotiation [24]byte - copy(expectedSecureRenegotiation[:], c.clientFinished[:]) - copy(expectedSecureRenegotiation[12:], c.serverFinished[:]) - if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: incorrect renegotiation extension contents") - } - } - - if hs.serverHello.alpnProtocol != "" { - if len(hs.hello.alpnProtocols) == 0 { - c.sendAlert(alertUnsupportedExtension) - return false, errors.New("tls: server advertised unrequested ALPN extension") - } - if mutualProtocol([]string{hs.serverHello.alpnProtocol}, hs.hello.alpnProtocols) == "" { - c.sendAlert(alertUnsupportedExtension) - return false, errors.New("tls: server selected unadvertised ALPN protocol") - } - c.clientProtocol = hs.serverHello.alpnProtocol - } - - c.scts = hs.serverHello.scts - - if !hs.serverResumedSession() { - return false, nil - } - - if hs.session.vers != c.vers { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: server resumed a session with a different version") - } - - if hs.session.cipherSuite != hs.suite.id { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: server resumed a session with a different cipher suite") - } - - // Restore masterSecret, peerCerts, and ocspResponse from previous state - hs.masterSecret = hs.session.masterSecret - c.peerCertificates = hs.session.serverCertificates - c.verifiedChains = hs.session.verifiedChains - c.ocspResponse = hs.session.ocspResponse - // Let the ServerHello SCTs override the session SCTs from the original - // connection, if any are provided - if len(c.scts) == 0 && len(hs.session.scts) != 0 { - c.scts = hs.session.scts - } - - return true, nil -} - -func (hs *clientHandshakeState) readFinished(out []byte) error { - c := hs.c - - if err := c.readChangeCipherSpec(); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - serverFinished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(serverFinished, msg) - } - - verify := hs.finishedHash.serverSum(hs.masterSecret) - if len(verify) != len(serverFinished.verifyData) || - subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: server's Finished message was incorrect") - } - hs.finishedHash.Write(serverFinished.marshal()) - copy(out, verify) - return nil -} - -func (hs *clientHandshakeState) readSessionTicket() error { - if !hs.serverHello.ticketSupported { - return nil - } - - c := hs.c - msg, err := c.readHandshake() - if err != nil { - return err - } - sessionTicketMsg, ok := msg.(*newSessionTicketMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(sessionTicketMsg, msg) - } - hs.finishedHash.Write(sessionTicketMsg.marshal()) - - hs.session = &clientSessionState{ - sessionTicket: sessionTicketMsg.ticket, - vers: c.vers, - cipherSuite: hs.suite.id, - masterSecret: hs.masterSecret, - serverCertificates: c.peerCertificates, - verifiedChains: c.verifiedChains, - receivedAt: c.config.time(), - ocspResponse: c.ocspResponse, - scts: c.scts, - } - - return nil -} - -func (hs *clientHandshakeState) sendFinished(out []byte) error { - c := hs.c - - if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { - return err - } - - finished := new(finishedMsg) - finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) - hs.finishedHash.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - copy(out, finished.verifyData) - return nil -} - -// verifyServerCertificate parses and verifies the provided chain, setting -// c.verifiedChains and c.peerCertificates or sending the appropriate alert. -func (c *Conn) verifyServerCertificate(certificates [][]byte) error { - certs := make([]*x509.Certificate, len(certificates)) - for i, asn1Data := range certificates { - cert, err := x509.ParseCertificate(asn1Data) - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to parse certificate from server: " + err.Error()) - } - certs[i] = cert - } - - if !c.config.InsecureSkipVerify { - opts := x509.VerifyOptions{ - Roots: c.config.RootCAs, - CurrentTime: c.config.time(), - DNSName: c.config.ServerName, - Intermediates: x509.NewCertPool(), - } - for _, cert := range certs[1:] { - opts.Intermediates.AddCert(cert) - } - var err error - c.verifiedChains, err = certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - switch certs[0].PublicKey.(type) { - case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey: - break - default: - c.sendAlert(alertUnsupportedCertificate) - return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey) - } - - c.peerCertificates = certs - - if c.config.VerifyPeerCertificate != nil { - if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - return nil -} - -// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS -// <= 1.2 CertificateRequest, making an effort to fill in missing information. -func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo { - cri := &certificateRequestInfo{ - AcceptableCAs: certReq.certificateAuthorities, - Version: vers, - } - - var rsaAvail, ecAvail bool - for _, certType := range certReq.certificateTypes { - switch certType { - case certTypeRSASign: - rsaAvail = true - case certTypeECDSASign: - ecAvail = true - } - } - - if !certReq.hasSignatureAlgorithm { - // Prior to TLS 1.2, signature schemes did not exist. In this case we - // make up a list based on the acceptable certificate types, to help - // GetClientCertificate and SupportsCertificate select the right certificate. - // The hash part of the SignatureScheme is a lie here, because - // TLS 1.0 and 1.1 always use MD5+SHA1 for RSA and SHA1 for ECDSA. - switch { - case rsaAvail && ecAvail: - cri.SignatureSchemes = []SignatureScheme{ - ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, - PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1, - } - case rsaAvail: - cri.SignatureSchemes = []SignatureScheme{ - PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1, - } - case ecAvail: - cri.SignatureSchemes = []SignatureScheme{ - ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, - } - } - return toCertificateRequestInfo(cri) - } - - // Filter the signature schemes based on the certificate types. - // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated"). - cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms)) - for _, sigScheme := range certReq.supportedSignatureAlgorithms { - sigType, _, err := typeAndHashFromSignatureScheme(sigScheme) - if err != nil { - continue - } - switch sigType { - case signatureECDSA, signatureEd25519: - if ecAvail { - cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme) - } - case signatureRSAPSS, signaturePKCS1v15: - if rsaAvail { - cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme) - } - } - } - - return toCertificateRequestInfo(cri) -} - -func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) { - if c.config.GetClientCertificate != nil { - return c.config.GetClientCertificate(cri) - } - - for _, chain := range c.config.Certificates { - if err := cri.SupportsCertificate(&chain); err != nil { - continue - } - return &chain, nil - } - - // No acceptable certificate found. Don't send a certificate. - return new(Certificate), nil -} - -const clientSessionCacheKeyPrefix = "qtls-" - -// clientSessionCacheKey returns a key used to cache sessionTickets that could -// be used to resume previously negotiated TLS sessions with a server. -func clientSessionCacheKey(serverAddr net.Addr, config *config) string { - if len(config.ServerName) > 0 { - return clientSessionCacheKeyPrefix + config.ServerName - } - return clientSessionCacheKeyPrefix + serverAddr.String() -} - -// mutualProtocol finds the mutual ALPN protocol given list of possible -// protocols and a list of the preference order. -func mutualProtocol(protos, preferenceProtos []string) string { - for _, s := range preferenceProtos { - for _, c := range protos { - if s == c { - return s - } - } - } - return "" -} - -// hostnameInSNI converts name into an appropriate hostname for SNI. -// Literal IP addresses and absolute FQDNs are not permitted as SNI values. -// See RFC 6066, Section 3. -func hostnameInSNI(name string) string { - host := name - if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' { - host = host[1 : len(host)-1] - } - if i := strings.LastIndex(host, "%"); i > 0 { - host = host[:i] - } - if net.ParseIP(host) != nil { - return "" - } - for len(name) > 0 && name[len(name)-1] == '.' { - name = name[:len(name)-1] - } - return name -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_client_tls13.go b/vendor/github.com/marten-seemann/qtls-go1-16/handshake_client_tls13.go deleted file mode 100644 index fb70cec06..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_client_tls13.go +++ /dev/null @@ -1,740 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "bytes" - "crypto" - "crypto/hmac" - "crypto/rsa" - "encoding/binary" - "errors" - "fmt" - "hash" - "sync/atomic" - "time" - - "golang.org/x/crypto/cryptobyte" -) - -type clientHandshakeStateTLS13 struct { - c *Conn - serverHello *serverHelloMsg - hello *clientHelloMsg - ecdheParams ecdheParameters - - session *clientSessionState - earlySecret []byte - binderKey []byte - - certReq *certificateRequestMsgTLS13 - usingPSK bool - sentDummyCCS bool - suite *cipherSuiteTLS13 - transcript hash.Hash - masterSecret []byte - trafficSecret []byte // client_application_traffic_secret_0 -} - -// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and, -// optionally, hs.session, hs.earlySecret and hs.binderKey to be set. -func (hs *clientHandshakeStateTLS13) handshake() error { - c := hs.c - - // The server must not select TLS 1.3 in a renegotiation. See RFC 8446, - // sections 4.1.2 and 4.1.3. - if c.handshakes > 0 { - c.sendAlert(alertProtocolVersion) - return errors.New("tls: server selected TLS 1.3 in a renegotiation") - } - - // Consistency check on the presence of a keyShare and its parameters. - if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 { - return c.sendAlert(alertInternalError) - } - - if err := hs.checkServerHelloOrHRR(); err != nil { - return err - } - - hs.transcript = hs.suite.hash.New() - hs.transcript.Write(hs.hello.marshal()) - - if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - if err := hs.processHelloRetryRequest(); err != nil { - return err - } - } - - hs.transcript.Write(hs.serverHello.marshal()) - - c.buffering = true - if err := hs.processServerHello(); err != nil { - return err - } - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - if err := hs.establishHandshakeKeys(); err != nil { - return err - } - if err := hs.readServerParameters(); err != nil { - return err - } - if err := hs.readServerCertificate(); err != nil { - return err - } - if err := hs.readServerFinished(); err != nil { - return err - } - if err := hs.sendClientCertificate(); err != nil { - return err - } - if err := hs.sendClientFinished(); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -// checkServerHelloOrHRR does validity checks that apply to both ServerHello and -// HelloRetryRequest messages. It sets hs.suite. -func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error { - c := hs.c - - if hs.serverHello.supportedVersion == 0 { - c.sendAlert(alertMissingExtension) - return errors.New("tls: server selected TLS 1.3 using the legacy version field") - } - - if hs.serverHello.supportedVersion != VersionTLS13 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected an invalid version after a HelloRetryRequest") - } - - if hs.serverHello.vers != VersionTLS12 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server sent an incorrect legacy version") - } - - if hs.serverHello.ocspStapling || - hs.serverHello.ticketSupported || - hs.serverHello.secureRenegotiationSupported || - len(hs.serverHello.secureRenegotiation) != 0 || - len(hs.serverHello.alpnProtocol) != 0 || - len(hs.serverHello.scts) != 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3") - } - - if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server did not echo the legacy session ID") - } - - if hs.serverHello.compressionMethod != compressionNone { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected unsupported compression format") - } - - selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite) - if hs.suite != nil && selectedSuite != hs.suite { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server changed cipher suite after a HelloRetryRequest") - } - if selectedSuite == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server chose an unconfigured cipher suite") - } - hs.suite = selectedSuite - c.cipherSuite = hs.suite.id - - return nil -} - -// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility -// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. -func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error { - if hs.sentDummyCCS { - return nil - } - hs.sentDummyCCS = true - - _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - return err -} - -// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and -// resends hs.hello, and reads the new ServerHello into hs.serverHello. -func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error { - c := hs.c - - // The first ClientHello gets double-hashed into the transcript upon a - // HelloRetryRequest. (The idea is that the server might offload transcript - // storage to the client in the cookie.) See RFC 8446, Section 4.4.1. - chHash := hs.transcript.Sum(nil) - hs.transcript.Reset() - hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) - hs.transcript.Write(chHash) - hs.transcript.Write(hs.serverHello.marshal()) - - // The only HelloRetryRequest extensions we support are key_share and - // cookie, and clients must abort the handshake if the HRR would not result - // in any change in the ClientHello. - if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server sent an unnecessary HelloRetryRequest message") - } - - if hs.serverHello.cookie != nil { - hs.hello.cookie = hs.serverHello.cookie - } - - if hs.serverHello.serverShare.group != 0 { - c.sendAlert(alertDecodeError) - return errors.New("tls: received malformed key_share extension") - } - - // If the server sent a key_share extension selecting a group, ensure it's - // a group we advertised but did not send a key share for, and send a key - // share for it this time. - if curveID := hs.serverHello.selectedGroup; curveID != 0 { - curveOK := false - for _, id := range hs.hello.supportedCurves { - if id == curveID { - curveOK = true - break - } - } - if !curveOK { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected unsupported group") - } - if hs.ecdheParams.CurveID() == curveID { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share") - } - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - c.sendAlert(alertInternalError) - return errors.New("tls: CurvePreferences includes unsupported curve") - } - params, err := generateECDHEParameters(c.config.rand(), curveID) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - hs.ecdheParams = params - hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} - } - - hs.hello.raw = nil - if len(hs.hello.pskIdentities) > 0 { - pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) - if pskSuite == nil { - return c.sendAlert(alertInternalError) - } - if pskSuite.hash == hs.suite.hash { - // Update binders and obfuscated_ticket_age. - ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond) - hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd - - transcript := hs.suite.hash.New() - transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) - transcript.Write(chHash) - transcript.Write(hs.serverHello.marshal()) - transcript.Write(hs.hello.marshalWithoutBinders()) - pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)} - hs.hello.updateBinders(pskBinders) - } else { - // Server selected a cipher suite incompatible with the PSK. - hs.hello.pskIdentities = nil - hs.hello.pskBinders = nil - } - } - - if hs.hello.earlyData && c.extraConfig != nil && c.extraConfig.Rejected0RTT != nil { - c.extraConfig.Rejected0RTT() - } - hs.hello.earlyData = false // disable 0-RTT - - hs.transcript.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - serverHello, ok := msg.(*serverHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(serverHello, msg) - } - hs.serverHello = serverHello - - if err := hs.checkServerHelloOrHRR(); err != nil { - return err - } - - return nil -} - -func (hs *clientHandshakeStateTLS13) processServerHello() error { - c := hs.c - - if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { - c.sendAlert(alertUnexpectedMessage) - return errors.New("tls: server sent two HelloRetryRequest messages") - } - - if len(hs.serverHello.cookie) != 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server sent a cookie in a normal ServerHello") - } - - if hs.serverHello.selectedGroup != 0 { - c.sendAlert(alertDecodeError) - return errors.New("tls: malformed key_share extension") - } - - if hs.serverHello.serverShare.group == 0 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server did not send a key share") - } - if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected unsupported group") - } - - if !hs.serverHello.selectedIdentityPresent { - return nil - } - - if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected an invalid PSK") - } - - if len(hs.hello.pskIdentities) != 1 || hs.session == nil { - return c.sendAlert(alertInternalError) - } - pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) - if pskSuite == nil { - return c.sendAlert(alertInternalError) - } - if pskSuite.hash != hs.suite.hash { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected an invalid PSK and cipher suite pair") - } - - hs.usingPSK = true - c.didResume = true - c.peerCertificates = hs.session.serverCertificates - c.verifiedChains = hs.session.verifiedChains - c.ocspResponse = hs.session.ocspResponse - c.scts = hs.session.scts - return nil -} - -func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error { - c := hs.c - - sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data) - if sharedKey == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid server key share") - } - - earlySecret := hs.earlySecret - if !hs.usingPSK { - earlySecret = hs.suite.extract(nil, nil) - } - handshakeSecret := hs.suite.extract(sharedKey, - hs.suite.deriveSecret(earlySecret, "derived", nil)) - - clientSecret := hs.suite.deriveSecret(handshakeSecret, - clientHandshakeTrafficLabel, hs.transcript) - c.out.exportKey(EncryptionHandshake, hs.suite, clientSecret) - c.out.setTrafficSecret(hs.suite, clientSecret) - serverSecret := hs.suite.deriveSecret(handshakeSecret, - serverHandshakeTrafficLabel, hs.transcript) - c.in.exportKey(EncryptionHandshake, hs.suite, serverSecret) - c.in.setTrafficSecret(hs.suite, serverSecret) - - err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - hs.masterSecret = hs.suite.extract(nil, - hs.suite.deriveSecret(handshakeSecret, "derived", nil)) - - return nil -} - -func (hs *clientHandshakeStateTLS13) readServerParameters() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - - encryptedExtensions, ok := msg.(*encryptedExtensionsMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(encryptedExtensions, msg) - } - // Notify the caller if 0-RTT was rejected. - if !encryptedExtensions.earlyData && hs.hello.earlyData && c.extraConfig != nil && c.extraConfig.Rejected0RTT != nil { - c.extraConfig.Rejected0RTT() - } - c.used0RTT = encryptedExtensions.earlyData - if hs.c.extraConfig != nil && hs.c.extraConfig.ReceivedExtensions != nil { - hs.c.extraConfig.ReceivedExtensions(typeEncryptedExtensions, encryptedExtensions.additionalExtensions) - } - hs.transcript.Write(encryptedExtensions.marshal()) - - if c.extraConfig != nil && c.extraConfig.EnforceNextProtoSelection { - if len(encryptedExtensions.alpnProtocol) == 0 { - // the server didn't select an ALPN - c.sendAlert(alertNoApplicationProtocol) - return errors.New("ALPN negotiation failed. Server didn't offer any protocols") - } - if mutualProtocol([]string{encryptedExtensions.alpnProtocol}, hs.c.config.NextProtos) == "" { - // the protocol selected by the server was not offered - c.sendAlert(alertNoApplicationProtocol) - return fmt.Errorf("ALPN negotiation failed. Server offered: %q", encryptedExtensions.alpnProtocol) - } - } - if encryptedExtensions.alpnProtocol != "" { - if len(hs.hello.alpnProtocols) == 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server advertised unrequested ALPN extension") - } - if mutualProtocol([]string{encryptedExtensions.alpnProtocol}, hs.hello.alpnProtocols) == "" { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server selected unadvertised ALPN protocol") - } - c.clientProtocol = encryptedExtensions.alpnProtocol - } - return nil -} - -func (hs *clientHandshakeStateTLS13) readServerCertificate() error { - c := hs.c - - // Either a PSK or a certificate is always used, but not both. - // See RFC 8446, Section 4.1.1. - if hs.usingPSK { - // Make sure the connection is still being verified whether or not this - // is a resumption. Resumptions currently don't reverify certificates so - // they don't call verifyServerCertificate. See Issue 31641. - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - return nil - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - certReq, ok := msg.(*certificateRequestMsgTLS13) - if ok { - hs.transcript.Write(certReq.marshal()) - - hs.certReq = certReq - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - certMsg, ok := msg.(*certificateMsgTLS13) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - if len(certMsg.certificate.Certificate) == 0 { - c.sendAlert(alertDecodeError) - return errors.New("tls: received empty certificates message") - } - hs.transcript.Write(certMsg.marshal()) - - c.scts = certMsg.certificate.SignedCertificateTimestamps - c.ocspResponse = certMsg.certificate.OCSPStaple - - if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil { - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certVerify, msg) - } - - // See RFC 8446, Section 4.4.3. - if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: certificate used with invalid signature algorithm") - } - sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: certificate used with invalid signature algorithm") - } - signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) - if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, - sigHash, signed, certVerify.signature); err != nil { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid signature by the server certificate: " + err.Error()) - } - - hs.transcript.Write(certVerify.marshal()) - - return nil -} - -func (hs *clientHandshakeStateTLS13) readServerFinished() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - - finished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(finished, msg) - } - - expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) - if !hmac.Equal(expectedMAC, finished.verifyData) { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid server finished hash") - } - - hs.transcript.Write(finished.marshal()) - - // Derive secrets that take context through the server Finished. - - hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, - clientApplicationTrafficLabel, hs.transcript) - serverSecret := hs.suite.deriveSecret(hs.masterSecret, - serverApplicationTrafficLabel, hs.transcript) - c.in.exportKey(EncryptionApplication, hs.suite, serverSecret) - c.in.setTrafficSecret(hs.suite, serverSecret) - - err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) - - return nil -} - -func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { - c := hs.c - - if hs.certReq == nil { - return nil - } - - cert, err := c.getClientCertificate(toCertificateRequestInfo(&certificateRequestInfo{ - AcceptableCAs: hs.certReq.certificateAuthorities, - SignatureSchemes: hs.certReq.supportedSignatureAlgorithms, - Version: c.vers, - })) - if err != nil { - return err - } - - certMsg := new(certificateMsgTLS13) - - certMsg.certificate = *cert - certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0 - certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0 - - hs.transcript.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - - // If we sent an empty certificate message, skip the CertificateVerify. - if len(cert.Certificate) == 0 { - return nil - } - - certVerifyMsg := new(certificateVerifyMsg) - certVerifyMsg.hasSignatureAlgorithm = true - - certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms) - if err != nil { - // getClientCertificate returned a certificate incompatible with the - // CertificateRequestInfo supported signature algorithms. - c.sendAlert(alertHandshakeFailure) - return err - } - - sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - - signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) - if err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to sign handshake: " + err.Error()) - } - certVerifyMsg.signature = sig - - hs.transcript.Write(certVerifyMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *clientHandshakeStateTLS13) sendClientFinished() error { - c := hs.c - - finished := &finishedMsg{ - verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), - } - - hs.transcript.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - - c.out.exportKey(EncryptionApplication, hs.suite, hs.trafficSecret) - c.out.setTrafficSecret(hs.suite, hs.trafficSecret) - - if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil { - c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, - resumptionLabel, hs.transcript) - } - - return nil -} - -func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error { - if !c.isClient { - c.sendAlert(alertUnexpectedMessage) - return errors.New("tls: received new session ticket from a client") - } - - if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { - return nil - } - - // See RFC 8446, Section 4.6.1. - if msg.lifetime == 0 { - return nil - } - lifetime := time.Duration(msg.lifetime) * time.Second - if lifetime > maxSessionTicketLifetime { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: received a session ticket with invalid lifetime") - } - - cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) - if cipherSuite == nil || c.resumptionSecret == nil { - return c.sendAlert(alertInternalError) - } - - // We need to save the max_early_data_size that the server sent us, in order - // to decide if we're going to try 0-RTT with this ticket. - // However, at the same time, the qtls.ClientSessionTicket needs to be equal to - // the tls.ClientSessionTicket, so we can't just add a new field to the struct. - // We therefore abuse the nonce field (which is a byte slice) - nonceWithEarlyData := make([]byte, len(msg.nonce)+4) - binary.BigEndian.PutUint32(nonceWithEarlyData, msg.maxEarlyData) - copy(nonceWithEarlyData[4:], msg.nonce) - - var appData []byte - if c.extraConfig != nil && c.extraConfig.GetAppDataForSessionState != nil { - appData = c.extraConfig.GetAppDataForSessionState() - } - var b cryptobyte.Builder - b.AddUint16(clientSessionStateVersion) // revision - b.AddUint32(msg.maxEarlyData) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(appData) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(msg.nonce) - }) - - // Save the resumption_master_secret and nonce instead of deriving the PSK - // to do the least amount of work on NewSessionTicket messages before we - // know if the ticket will be used. Forward secrecy of resumed connections - // is guaranteed by the requirement for pskModeDHE. - session := &clientSessionState{ - sessionTicket: msg.label, - vers: c.vers, - cipherSuite: c.cipherSuite, - masterSecret: c.resumptionSecret, - serverCertificates: c.peerCertificates, - verifiedChains: c.verifiedChains, - receivedAt: c.config.time(), - nonce: b.BytesOrPanic(), - useBy: c.config.time().Add(lifetime), - ageAdd: msg.ageAdd, - ocspResponse: c.ocspResponse, - scts: c.scts, - } - - cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config) - c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(session)) - - return nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_messages.go b/vendor/github.com/marten-seemann/qtls-go1-16/handshake_messages.go deleted file mode 100644 index 1ab757626..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_messages.go +++ /dev/null @@ -1,1832 +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 qtls - -import ( - "fmt" - "strings" - - "golang.org/x/crypto/cryptobyte" -) - -// The marshalingFunction type is an adapter to allow the use of ordinary -// functions as cryptobyte.MarshalingValue. -type marshalingFunction func(b *cryptobyte.Builder) error - -func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error { - return f(b) -} - -// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If -// the length of the sequence is not the value specified, it produces an error. -func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) { - b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error { - if len(v) != n { - return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v)) - } - b.AddBytes(v) - return nil - })) -} - -// addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder. -func addUint64(b *cryptobyte.Builder, v uint64) { - b.AddUint32(uint32(v >> 32)) - b.AddUint32(uint32(v)) -} - -// readUint64 decodes a big-endian, 64-bit value into out and advances over it. -// It reports whether the read was successful. -func readUint64(s *cryptobyte.String, out *uint64) bool { - var hi, lo uint32 - if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) { - return false - } - *out = uint64(hi)<<32 | uint64(lo) - return true -} - -// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a -// []byte instead of a cryptobyte.String. -func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { - return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out)) -} - -// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a -// []byte instead of a cryptobyte.String. -func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { - return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out)) -} - -// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a -// []byte instead of a cryptobyte.String. -func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { - return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out)) -} - -type clientHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuites []uint16 - compressionMethods []uint8 - serverName string - ocspStapling bool - supportedCurves []CurveID - supportedPoints []uint8 - ticketSupported bool - sessionTicket []uint8 - supportedSignatureAlgorithms []SignatureScheme - supportedSignatureAlgorithmsCert []SignatureScheme - secureRenegotiationSupported bool - secureRenegotiation []byte - alpnProtocols []string - scts bool - supportedVersions []uint16 - cookie []byte - keyShares []keyShare - earlyData bool - pskModes []uint8 - pskIdentities []pskIdentity - pskBinders [][]byte - additionalExtensions []Extension -} - -func (m *clientHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeClientHello) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.vers) - addBytesWithLength(b, m.random, 32) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.sessionId) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, suite := range m.cipherSuites { - b.AddUint16(suite) - } - }) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.compressionMethods) - }) - - // If extensions aren't present, omit them. - var extensionsPresent bool - bWithoutExtensions := *b - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if len(m.serverName) > 0 { - // RFC 6066, Section 3 - b.AddUint16(extensionServerName) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(0) // name_type = host_name - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.serverName)) - }) - }) - }) - } - if m.ocspStapling { - // RFC 4366, Section 3.6 - b.AddUint16(extensionStatusRequest) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(1) // status_type = ocsp - b.AddUint16(0) // empty responder_id_list - b.AddUint16(0) // empty request_extensions - }) - } - if len(m.supportedCurves) > 0 { - // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 - b.AddUint16(extensionSupportedCurves) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, curve := range m.supportedCurves { - b.AddUint16(uint16(curve)) - } - }) - }) - } - if len(m.supportedPoints) > 0 { - // RFC 4492, Section 5.1.2 - b.AddUint16(extensionSupportedPoints) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.supportedPoints) - }) - }) - } - if m.ticketSupported { - // RFC 5077, Section 3.2 - b.AddUint16(extensionSessionTicket) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.sessionTicket) - }) - } - if len(m.supportedSignatureAlgorithms) > 0 { - // RFC 5246, Section 7.4.1.4.1 - b.AddUint16(extensionSignatureAlgorithms) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithms { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if len(m.supportedSignatureAlgorithmsCert) > 0 { - // RFC 8446, Section 4.2.3 - b.AddUint16(extensionSignatureAlgorithmsCert) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if m.secureRenegotiationSupported { - // RFC 5746, Section 3.2 - b.AddUint16(extensionRenegotiationInfo) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.secureRenegotiation) - }) - }) - } - if len(m.alpnProtocols) > 0 { - // RFC 7301, Section 3.1 - b.AddUint16(extensionALPN) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, proto := range m.alpnProtocols { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(proto)) - }) - } - }) - }) - } - if m.scts { - // RFC 6962, Section 3.3.1 - b.AddUint16(extensionSCT) - b.AddUint16(0) // empty extension_data - } - if len(m.supportedVersions) > 0 { - // RFC 8446, Section 4.2.1 - b.AddUint16(extensionSupportedVersions) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - for _, vers := range m.supportedVersions { - b.AddUint16(vers) - } - }) - }) - } - if len(m.cookie) > 0 { - // RFC 8446, Section 4.2.2 - b.AddUint16(extensionCookie) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.cookie) - }) - }) - } - if len(m.keyShares) > 0 { - // RFC 8446, Section 4.2.8 - b.AddUint16(extensionKeyShare) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, ks := range m.keyShares { - b.AddUint16(uint16(ks.group)) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ks.data) - }) - } - }) - }) - } - if m.earlyData { - // RFC 8446, Section 4.2.10 - b.AddUint16(extensionEarlyData) - b.AddUint16(0) // empty extension_data - } - if len(m.pskModes) > 0 { - // RFC 8446, Section 4.2.9 - b.AddUint16(extensionPSKModes) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.pskModes) - }) - }) - } - for _, ext := range m.additionalExtensions { - b.AddUint16(ext.Type) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ext.Data) - }) - } - if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension - // RFC 8446, Section 4.2.11 - b.AddUint16(extensionPreSharedKey) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, psk := range m.pskIdentities { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(psk.label) - }) - b.AddUint32(psk.obfuscatedTicketAge) - } - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, binder := range m.pskBinders { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(binder) - }) - } - }) - }) - } - - extensionsPresent = len(b.BytesOrPanic()) > 2 - }) - - if !extensionsPresent { - *b = bWithoutExtensions - } - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -// marshalWithoutBinders returns the ClientHello through the -// PreSharedKeyExtension.identities field, according to RFC 8446, Section -// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length. -func (m *clientHelloMsg) marshalWithoutBinders() []byte { - bindersLen := 2 // uint16 length prefix - for _, binder := range m.pskBinders { - bindersLen += 1 // uint8 length prefix - bindersLen += len(binder) - } - - fullMessage := m.marshal() - return fullMessage[:len(fullMessage)-bindersLen] -} - -// updateBinders updates the m.pskBinders field, if necessary updating the -// cached marshaled representation. The supplied binders must have the same -// length as the current m.pskBinders. -func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) { - if len(pskBinders) != len(m.pskBinders) { - panic("tls: internal error: pskBinders length mismatch") - } - for i := range m.pskBinders { - if len(pskBinders[i]) != len(m.pskBinders[i]) { - panic("tls: internal error: pskBinders length mismatch") - } - } - m.pskBinders = pskBinders - if m.raw != nil { - lenWithoutBinders := len(m.marshalWithoutBinders()) - // TODO(filippo): replace with NewFixedBuilder once CL 148882 is imported. - b := cryptobyte.NewBuilder(m.raw[:lenWithoutBinders]) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, binder := range m.pskBinders { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(binder) - }) - } - }) - if len(b.BytesOrPanic()) != len(m.raw) { - panic("tls: internal error: failed to update binders") - } - } -} - -func (m *clientHelloMsg) unmarshal(data []byte) bool { - *m = clientHelloMsg{raw: data} - s := cryptobyte.String(data) - - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) || - !readUint8LengthPrefixed(&s, &m.sessionId) { - return false - } - - var cipherSuites cryptobyte.String - if !s.ReadUint16LengthPrefixed(&cipherSuites) { - return false - } - m.cipherSuites = []uint16{} - m.secureRenegotiationSupported = false - for !cipherSuites.Empty() { - var suite uint16 - if !cipherSuites.ReadUint16(&suite) { - return false - } - if suite == scsvRenegotiation { - m.secureRenegotiationSupported = true - } - m.cipherSuites = append(m.cipherSuites, suite) - } - - if !readUint8LengthPrefixed(&s, &m.compressionMethods) { - return false - } - - if s.Empty() { - // ClientHello is optionally followed by extension data - return true - } - - var extensions cryptobyte.String - if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { - return false - } - - for !extensions.Empty() { - var ext uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&ext) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch ext { - case extensionServerName: - // RFC 6066, Section 3 - var nameList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() { - return false - } - for !nameList.Empty() { - var nameType uint8 - var serverName cryptobyte.String - if !nameList.ReadUint8(&nameType) || - !nameList.ReadUint16LengthPrefixed(&serverName) || - serverName.Empty() { - return false - } - if nameType != 0 { - continue - } - if len(m.serverName) != 0 { - // Multiple names of the same name_type are prohibited. - return false - } - m.serverName = string(serverName) - // An SNI value may not include a trailing dot. - if strings.HasSuffix(m.serverName, ".") { - return false - } - } - case extensionStatusRequest: - // RFC 4366, Section 3.6 - var statusType uint8 - var ignored cryptobyte.String - if !extData.ReadUint8(&statusType) || - !extData.ReadUint16LengthPrefixed(&ignored) || - !extData.ReadUint16LengthPrefixed(&ignored) { - return false - } - m.ocspStapling = statusType == statusTypeOCSP - case extensionSupportedCurves: - // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 - var curves cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() { - return false - } - for !curves.Empty() { - var curve uint16 - if !curves.ReadUint16(&curve) { - return false - } - m.supportedCurves = append(m.supportedCurves, CurveID(curve)) - } - case extensionSupportedPoints: - // RFC 4492, Section 5.1.2 - if !readUint8LengthPrefixed(&extData, &m.supportedPoints) || - len(m.supportedPoints) == 0 { - return false - } - case extensionSessionTicket: - // RFC 5077, Section 3.2 - m.ticketSupported = true - extData.ReadBytes(&m.sessionTicket, len(extData)) - case extensionSignatureAlgorithms: - // RFC 5246, Section 7.4.1.4.1 - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithms = append( - m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg)) - } - case extensionSignatureAlgorithmsCert: - // RFC 8446, Section 4.2.3 - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithmsCert = append( - m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg)) - } - case extensionRenegotiationInfo: - // RFC 5746, Section 3.2 - if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) { - return false - } - m.secureRenegotiationSupported = true - case extensionALPN: - // RFC 7301, Section 3.1 - var protoList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { - return false - } - for !protoList.Empty() { - var proto cryptobyte.String - if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() { - return false - } - m.alpnProtocols = append(m.alpnProtocols, string(proto)) - } - case extensionSCT: - // RFC 6962, Section 3.3.1 - m.scts = true - case extensionSupportedVersions: - // RFC 8446, Section 4.2.1 - var versList cryptobyte.String - if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() { - return false - } - for !versList.Empty() { - var vers uint16 - if !versList.ReadUint16(&vers) { - return false - } - m.supportedVersions = append(m.supportedVersions, vers) - } - case extensionCookie: - // RFC 8446, Section 4.2.2 - if !readUint16LengthPrefixed(&extData, &m.cookie) || - len(m.cookie) == 0 { - return false - } - case extensionKeyShare: - // RFC 8446, Section 4.2.8 - var clientShares cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&clientShares) { - return false - } - for !clientShares.Empty() { - var ks keyShare - if !clientShares.ReadUint16((*uint16)(&ks.group)) || - !readUint16LengthPrefixed(&clientShares, &ks.data) || - len(ks.data) == 0 { - return false - } - m.keyShares = append(m.keyShares, ks) - } - case extensionEarlyData: - // RFC 8446, Section 4.2.10 - m.earlyData = true - case extensionPSKModes: - // RFC 8446, Section 4.2.9 - if !readUint8LengthPrefixed(&extData, &m.pskModes) { - return false - } - case extensionPreSharedKey: - // RFC 8446, Section 4.2.11 - if !extensions.Empty() { - return false // pre_shared_key must be the last extension - } - var identities cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() { - return false - } - for !identities.Empty() { - var psk pskIdentity - if !readUint16LengthPrefixed(&identities, &psk.label) || - !identities.ReadUint32(&psk.obfuscatedTicketAge) || - len(psk.label) == 0 { - return false - } - m.pskIdentities = append(m.pskIdentities, psk) - } - var binders cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() { - return false - } - for !binders.Empty() { - var binder []byte - if !readUint8LengthPrefixed(&binders, &binder) || - len(binder) == 0 { - return false - } - m.pskBinders = append(m.pskBinders, binder) - } - default: - m.additionalExtensions = append(m.additionalExtensions, Extension{Type: ext, Data: extData}) - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type serverHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuite uint16 - compressionMethod uint8 - ocspStapling bool - ticketSupported bool - secureRenegotiationSupported bool - secureRenegotiation []byte - alpnProtocol string - scts [][]byte - supportedVersion uint16 - serverShare keyShare - selectedIdentityPresent bool - selectedIdentity uint16 - supportedPoints []uint8 - - // HelloRetryRequest extensions - cookie []byte - selectedGroup CurveID -} - -func (m *serverHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeServerHello) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.vers) - addBytesWithLength(b, m.random, 32) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.sessionId) - }) - b.AddUint16(m.cipherSuite) - b.AddUint8(m.compressionMethod) - - // If extensions aren't present, omit them. - var extensionsPresent bool - bWithoutExtensions := *b - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.ocspStapling { - b.AddUint16(extensionStatusRequest) - b.AddUint16(0) // empty extension_data - } - if m.ticketSupported { - b.AddUint16(extensionSessionTicket) - b.AddUint16(0) // empty extension_data - } - if m.secureRenegotiationSupported { - b.AddUint16(extensionRenegotiationInfo) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.secureRenegotiation) - }) - }) - } - if len(m.alpnProtocol) > 0 { - b.AddUint16(extensionALPN) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.alpnProtocol)) - }) - }) - }) - } - if len(m.scts) > 0 { - b.AddUint16(extensionSCT) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sct := range m.scts { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(sct) - }) - } - }) - }) - } - if m.supportedVersion != 0 { - b.AddUint16(extensionSupportedVersions) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.supportedVersion) - }) - } - if m.serverShare.group != 0 { - b.AddUint16(extensionKeyShare) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(uint16(m.serverShare.group)) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.serverShare.data) - }) - }) - } - if m.selectedIdentityPresent { - b.AddUint16(extensionPreSharedKey) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.selectedIdentity) - }) - } - - if len(m.cookie) > 0 { - b.AddUint16(extensionCookie) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.cookie) - }) - }) - } - if m.selectedGroup != 0 { - b.AddUint16(extensionKeyShare) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(uint16(m.selectedGroup)) - }) - } - if len(m.supportedPoints) > 0 { - b.AddUint16(extensionSupportedPoints) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.supportedPoints) - }) - }) - } - - extensionsPresent = len(b.BytesOrPanic()) > 2 - }) - - if !extensionsPresent { - *b = bWithoutExtensions - } - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *serverHelloMsg) unmarshal(data []byte) bool { - *m = serverHelloMsg{raw: data} - s := cryptobyte.String(data) - - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) || - !readUint8LengthPrefixed(&s, &m.sessionId) || - !s.ReadUint16(&m.cipherSuite) || - !s.ReadUint8(&m.compressionMethod) { - return false - } - - if s.Empty() { - // ServerHello is optionally followed by extension data - return true - } - - var extensions cryptobyte.String - if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { - return false - } - - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch extension { - case extensionStatusRequest: - m.ocspStapling = true - case extensionSessionTicket: - m.ticketSupported = true - case extensionRenegotiationInfo: - if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) { - return false - } - m.secureRenegotiationSupported = true - case extensionALPN: - var protoList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { - return false - } - var proto cryptobyte.String - if !protoList.ReadUint8LengthPrefixed(&proto) || - proto.Empty() || !protoList.Empty() { - return false - } - m.alpnProtocol = string(proto) - case extensionSCT: - var sctList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() { - return false - } - for !sctList.Empty() { - var sct []byte - if !readUint16LengthPrefixed(&sctList, &sct) || - len(sct) == 0 { - return false - } - m.scts = append(m.scts, sct) - } - case extensionSupportedVersions: - if !extData.ReadUint16(&m.supportedVersion) { - return false - } - case extensionCookie: - if !readUint16LengthPrefixed(&extData, &m.cookie) || - len(m.cookie) == 0 { - return false - } - case extensionKeyShare: - // This extension has different formats in SH and HRR, accept either - // and let the handshake logic decide. See RFC 8446, Section 4.2.8. - if len(extData) == 2 { - if !extData.ReadUint16((*uint16)(&m.selectedGroup)) { - return false - } - } else { - if !extData.ReadUint16((*uint16)(&m.serverShare.group)) || - !readUint16LengthPrefixed(&extData, &m.serverShare.data) { - return false - } - } - case extensionPreSharedKey: - m.selectedIdentityPresent = true - if !extData.ReadUint16(&m.selectedIdentity) { - return false - } - case extensionSupportedPoints: - // RFC 4492, Section 5.1.2 - if !readUint8LengthPrefixed(&extData, &m.supportedPoints) || - len(m.supportedPoints) == 0 { - return false - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type encryptedExtensionsMsg struct { - raw []byte - alpnProtocol string - earlyData bool - - additionalExtensions []Extension -} - -func (m *encryptedExtensionsMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeEncryptedExtensions) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if len(m.alpnProtocol) > 0 { - b.AddUint16(extensionALPN) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.alpnProtocol)) - }) - }) - }) - } - if m.earlyData { - // RFC 8446, Section 4.2.10 - b.AddUint16(extensionEarlyData) - b.AddUint16(0) // empty extension_data - } - for _, ext := range m.additionalExtensions { - b.AddUint16(ext.Type) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ext.Data) - }) - } - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool { - *m = encryptedExtensionsMsg{raw: data} - s := cryptobyte.String(data) - - var extensions cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { - return false - } - - for !extensions.Empty() { - var ext uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&ext) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch ext { - case extensionALPN: - var protoList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { - return false - } - var proto cryptobyte.String - if !protoList.ReadUint8LengthPrefixed(&proto) || - proto.Empty() || !protoList.Empty() { - return false - } - m.alpnProtocol = string(proto) - case extensionEarlyData: - m.earlyData = true - default: - m.additionalExtensions = append(m.additionalExtensions, Extension{Type: ext, Data: extData}) - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type endOfEarlyDataMsg struct{} - -func (m *endOfEarlyDataMsg) marshal() []byte { - x := make([]byte, 4) - x[0] = typeEndOfEarlyData - return x -} - -func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} - -type keyUpdateMsg struct { - raw []byte - updateRequested bool -} - -func (m *keyUpdateMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeKeyUpdate) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - if m.updateRequested { - b.AddUint8(1) - } else { - b.AddUint8(0) - } - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *keyUpdateMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - - var updateRequested uint8 - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8(&updateRequested) || !s.Empty() { - return false - } - switch updateRequested { - case 0: - m.updateRequested = false - case 1: - m.updateRequested = true - default: - return false - } - return true -} - -type newSessionTicketMsgTLS13 struct { - raw []byte - lifetime uint32 - ageAdd uint32 - nonce []byte - label []byte - maxEarlyData uint32 -} - -func (m *newSessionTicketMsgTLS13) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeNewSessionTicket) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint32(m.lifetime) - b.AddUint32(m.ageAdd) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.nonce) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.label) - }) - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.maxEarlyData > 0 { - b.AddUint16(extensionEarlyData) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint32(m.maxEarlyData) - }) - } - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool { - *m = newSessionTicketMsgTLS13{raw: data} - s := cryptobyte.String(data) - - var extensions cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint32(&m.lifetime) || - !s.ReadUint32(&m.ageAdd) || - !readUint8LengthPrefixed(&s, &m.nonce) || - !readUint16LengthPrefixed(&s, &m.label) || - !s.ReadUint16LengthPrefixed(&extensions) || - !s.Empty() { - return false - } - - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch extension { - case extensionEarlyData: - if !extData.ReadUint32(&m.maxEarlyData) { - return false - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type certificateRequestMsgTLS13 struct { - raw []byte - ocspStapling bool - scts bool - supportedSignatureAlgorithms []SignatureScheme - supportedSignatureAlgorithmsCert []SignatureScheme - certificateAuthorities [][]byte -} - -func (m *certificateRequestMsgTLS13) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificateRequest) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - // certificate_request_context (SHALL be zero length unless used for - // post-handshake authentication) - b.AddUint8(0) - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.ocspStapling { - b.AddUint16(extensionStatusRequest) - b.AddUint16(0) // empty extension_data - } - if m.scts { - // RFC 8446, Section 4.4.2.1 makes no mention of - // signed_certificate_timestamp in CertificateRequest, but - // "Extensions in the Certificate message from the client MUST - // correspond to extensions in the CertificateRequest message - // from the server." and it appears in the table in Section 4.2. - b.AddUint16(extensionSCT) - b.AddUint16(0) // empty extension_data - } - if len(m.supportedSignatureAlgorithms) > 0 { - b.AddUint16(extensionSignatureAlgorithms) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithms { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if len(m.supportedSignatureAlgorithmsCert) > 0 { - b.AddUint16(extensionSignatureAlgorithmsCert) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if len(m.certificateAuthorities) > 0 { - b.AddUint16(extensionCertificateAuthorities) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, ca := range m.certificateAuthorities { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ca) - }) - } - }) - }) - } - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool { - *m = certificateRequestMsgTLS13{raw: data} - s := cryptobyte.String(data) - - var context, extensions cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8LengthPrefixed(&context) || !context.Empty() || - !s.ReadUint16LengthPrefixed(&extensions) || - !s.Empty() { - return false - } - - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch extension { - case extensionStatusRequest: - m.ocspStapling = true - case extensionSCT: - m.scts = true - case extensionSignatureAlgorithms: - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithms = append( - m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg)) - } - case extensionSignatureAlgorithmsCert: - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithmsCert = append( - m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg)) - } - case extensionCertificateAuthorities: - var auths cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() { - return false - } - for !auths.Empty() { - var ca []byte - if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 { - return false - } - m.certificateAuthorities = append(m.certificateAuthorities, ca) - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type certificateMsg struct { - raw []byte - certificates [][]byte -} - -func (m *certificateMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - var i int - for _, slice := range m.certificates { - i += len(slice) - } - - length := 3 + 3*len(m.certificates) + i - x = make([]byte, 4+length) - x[0] = typeCertificate - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - certificateOctets := length - 3 - x[4] = uint8(certificateOctets >> 16) - x[5] = uint8(certificateOctets >> 8) - x[6] = uint8(certificateOctets) - - y := x[7:] - for _, slice := range m.certificates { - y[0] = uint8(len(slice) >> 16) - y[1] = uint8(len(slice) >> 8) - y[2] = uint8(len(slice)) - copy(y[3:], slice) - y = y[3+len(slice):] - } - - m.raw = x - return -} - -func (m *certificateMsg) unmarshal(data []byte) bool { - if len(data) < 7 { - return false - } - - m.raw = data - certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6]) - if uint32(len(data)) != certsLen+7 { - return false - } - - numCerts := 0 - d := data[7:] - for certsLen > 0 { - if len(d) < 4 { - return false - } - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - if uint32(len(d)) < 3+certLen { - return false - } - d = d[3+certLen:] - certsLen -= 3 + certLen - numCerts++ - } - - m.certificates = make([][]byte, numCerts) - d = data[7:] - for i := 0; i < numCerts; i++ { - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - m.certificates[i] = d[3 : 3+certLen] - d = d[3+certLen:] - } - - return true -} - -type certificateMsgTLS13 struct { - raw []byte - certificate Certificate - ocspStapling bool - scts bool -} - -func (m *certificateMsgTLS13) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificate) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(0) // certificate_request_context - - certificate := m.certificate - if !m.ocspStapling { - certificate.OCSPStaple = nil - } - if !m.scts { - certificate.SignedCertificateTimestamps = nil - } - marshalCertificate(b, certificate) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) { - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - for i, cert := range certificate.Certificate { - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(cert) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if i > 0 { - // This library only supports OCSP and SCT for leaf certificates. - return - } - if certificate.OCSPStaple != nil { - b.AddUint16(extensionStatusRequest) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(statusTypeOCSP) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(certificate.OCSPStaple) - }) - }) - } - if certificate.SignedCertificateTimestamps != nil { - b.AddUint16(extensionSCT) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sct := range certificate.SignedCertificateTimestamps { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(sct) - }) - } - }) - }) - } - }) - } - }) -} - -func (m *certificateMsgTLS13) unmarshal(data []byte) bool { - *m = certificateMsgTLS13{raw: data} - s := cryptobyte.String(data) - - var context cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8LengthPrefixed(&context) || !context.Empty() || - !unmarshalCertificate(&s, &m.certificate) || - !s.Empty() { - return false - } - - m.scts = m.certificate.SignedCertificateTimestamps != nil - m.ocspStapling = m.certificate.OCSPStaple != nil - - return true -} - -func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool { - var certList cryptobyte.String - if !s.ReadUint24LengthPrefixed(&certList) { - return false - } - for !certList.Empty() { - var cert []byte - var extensions cryptobyte.String - if !readUint24LengthPrefixed(&certList, &cert) || - !certList.ReadUint16LengthPrefixed(&extensions) { - return false - } - certificate.Certificate = append(certificate.Certificate, cert) - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - if len(certificate.Certificate) > 1 { - // This library only supports OCSP and SCT for leaf certificates. - continue - } - - switch extension { - case extensionStatusRequest: - var statusType uint8 - if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP || - !readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) || - len(certificate.OCSPStaple) == 0 { - return false - } - case extensionSCT: - var sctList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() { - return false - } - for !sctList.Empty() { - var sct []byte - if !readUint16LengthPrefixed(&sctList, &sct) || - len(sct) == 0 { - return false - } - certificate.SignedCertificateTimestamps = append( - certificate.SignedCertificateTimestamps, sct) - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - } - return true -} - -type serverKeyExchangeMsg struct { - raw []byte - key []byte -} - -func (m *serverKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.key) - x := make([]byte, length+4) - x[0] = typeServerKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.key) - - m.raw = x - return x -} - -func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - m.key = data[4:] - return true -} - -type certificateStatusMsg struct { - raw []byte - response []byte -} - -func (m *certificateStatusMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificateStatus) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(statusTypeOCSP) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.response) - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *certificateStatusMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - - var statusType uint8 - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8(&statusType) || statusType != statusTypeOCSP || - !readUint24LengthPrefixed(&s, &m.response) || - len(m.response) == 0 || !s.Empty() { - return false - } - return true -} - -type serverHelloDoneMsg struct{} - -func (m *serverHelloDoneMsg) marshal() []byte { - x := make([]byte, 4) - x[0] = typeServerHelloDone - return x -} - -func (m *serverHelloDoneMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} - -type clientKeyExchangeMsg struct { - raw []byte - ciphertext []byte -} - -func (m *clientKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.ciphertext) - x := make([]byte, length+4) - x[0] = typeClientKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.ciphertext) - - m.raw = x - return x -} - -func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - l := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if l != len(data)-4 { - return false - } - m.ciphertext = data[4:] - return true -} - -type finishedMsg struct { - raw []byte - verifyData []byte -} - -func (m *finishedMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeFinished) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.verifyData) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *finishedMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - return s.Skip(1) && - readUint24LengthPrefixed(&s, &m.verifyData) && - s.Empty() -} - -type certificateRequestMsg struct { - raw []byte - // hasSignatureAlgorithm indicates whether this message includes a list of - // supported signature algorithms. This change was introduced with TLS 1.2. - hasSignatureAlgorithm bool - - certificateTypes []byte - supportedSignatureAlgorithms []SignatureScheme - certificateAuthorities [][]byte -} - -func (m *certificateRequestMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See RFC 4346, Section 7.4.4. - length := 1 + len(m.certificateTypes) + 2 - casLength := 0 - for _, ca := range m.certificateAuthorities { - casLength += 2 + len(ca) - } - length += casLength - - if m.hasSignatureAlgorithm { - length += 2 + 2*len(m.supportedSignatureAlgorithms) - } - - x = make([]byte, 4+length) - x[0] = typeCertificateRequest - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - x[4] = uint8(len(m.certificateTypes)) - - copy(x[5:], m.certificateTypes) - y := x[5+len(m.certificateTypes):] - - if m.hasSignatureAlgorithm { - n := len(m.supportedSignatureAlgorithms) * 2 - y[0] = uint8(n >> 8) - y[1] = uint8(n) - y = y[2:] - for _, sigAlgo := range m.supportedSignatureAlgorithms { - y[0] = uint8(sigAlgo >> 8) - y[1] = uint8(sigAlgo) - y = y[2:] - } - } - - y[0] = uint8(casLength >> 8) - y[1] = uint8(casLength) - y = y[2:] - for _, ca := range m.certificateAuthorities { - y[0] = uint8(len(ca) >> 8) - y[1] = uint8(len(ca)) - y = y[2:] - copy(y, ca) - y = y[len(ca):] - } - - m.raw = x - return -} - -func (m *certificateRequestMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 5 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - numCertTypes := int(data[4]) - data = data[5:] - if numCertTypes == 0 || len(data) <= numCertTypes { - return false - } - - m.certificateTypes = make([]byte, numCertTypes) - if copy(m.certificateTypes, data) != numCertTypes { - return false - } - - data = data[numCertTypes:] - - if m.hasSignatureAlgorithm { - if len(data) < 2 { - return false - } - sigAndHashLen := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if sigAndHashLen&1 != 0 { - return false - } - if len(data) < int(sigAndHashLen) { - return false - } - numSigAlgos := sigAndHashLen / 2 - m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos) - for i := range m.supportedSignatureAlgorithms { - m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1]) - data = data[2:] - } - } - - if len(data) < 2 { - return false - } - casLength := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if len(data) < int(casLength) { - return false - } - cas := make([]byte, casLength) - copy(cas, data) - data = data[casLength:] - - m.certificateAuthorities = nil - for len(cas) > 0 { - if len(cas) < 2 { - return false - } - caLen := uint16(cas[0])<<8 | uint16(cas[1]) - cas = cas[2:] - - if len(cas) < int(caLen) { - return false - } - - m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen]) - cas = cas[caLen:] - } - - return len(data) == 0 -} - -type certificateVerifyMsg struct { - raw []byte - hasSignatureAlgorithm bool // format change introduced in TLS 1.2 - signatureAlgorithm SignatureScheme - signature []byte -} - -func (m *certificateVerifyMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificateVerify) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - if m.hasSignatureAlgorithm { - b.AddUint16(uint16(m.signatureAlgorithm)) - } - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.signature) - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *certificateVerifyMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - - if !s.Skip(4) { // message type and uint24 length field - return false - } - if m.hasSignatureAlgorithm { - if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) { - return false - } - } - return readUint16LengthPrefixed(&s, &m.signature) && s.Empty() -} - -type newSessionTicketMsg struct { - raw []byte - ticket []byte -} - -func (m *newSessionTicketMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See RFC 5077, Section 3.3. - ticketLen := len(m.ticket) - length := 2 + 4 + ticketLen - x = make([]byte, 4+length) - x[0] = typeNewSessionTicket - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[8] = uint8(ticketLen >> 8) - x[9] = uint8(ticketLen) - copy(x[10:], m.ticket) - - m.raw = x - - return -} - -func (m *newSessionTicketMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 10 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - ticketLen := int(data[8])<<8 + int(data[9]) - if len(data)-10 != ticketLen { - return false - } - - m.ticket = data[10:] - - return true -} - -type helloRequestMsg struct { -} - -func (*helloRequestMsg) marshal() []byte { - return []byte{typeHelloRequest, 0, 0, 0} -} - -func (*helloRequestMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_server.go b/vendor/github.com/marten-seemann/qtls-go1-16/handshake_server.go deleted file mode 100644 index 5d39cc8fc..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_server.go +++ /dev/null @@ -1,878 +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 qtls - -import ( - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "errors" - "fmt" - "hash" - "io" - "sync/atomic" - "time" -) - -// serverHandshakeState contains details of a server handshake in progress. -// It's discarded once the handshake has completed. -type serverHandshakeState struct { - c *Conn - clientHello *clientHelloMsg - hello *serverHelloMsg - suite *cipherSuite - ecdheOk bool - ecSignOk bool - rsaDecryptOk bool - rsaSignOk bool - sessionState *sessionState - finishedHash finishedHash - masterSecret []byte - cert *Certificate -} - -// serverHandshake performs a TLS handshake as a server. -func (c *Conn) serverHandshake() error { - c.setAlternativeRecordLayer() - - clientHello, err := c.readClientHello() - if err != nil { - return err - } - - if c.vers == VersionTLS13 { - hs := serverHandshakeStateTLS13{ - c: c, - clientHello: clientHello, - } - return hs.handshake() - } else if c.extraConfig.usesAlternativeRecordLayer() { - // This should already have been caught by the check that the ClientHello doesn't - // offer any (supported) versions older than TLS 1.3. - // Check again to make sure we can't be tricked into using an older version. - c.sendAlert(alertProtocolVersion) - return errors.New("tls: negotiated TLS < 1.3 when using QUIC") - } - - hs := serverHandshakeState{ - c: c, - clientHello: clientHello, - } - return hs.handshake() -} - -func (hs *serverHandshakeState) handshake() error { - c := hs.c - - if err := hs.processClientHello(); err != nil { - return err - } - - // For an overview of TLS handshaking, see RFC 5246, Section 7.3. - c.buffering = true - if hs.checkForResumption() { - // The client has included a session ticket and so we do an abbreviated handshake. - c.didResume = true - if err := hs.doResumeHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.sendSessionTicket(); err != nil { - return err - } - if err := hs.sendFinished(c.serverFinished[:]); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - c.clientFinishedIsFirst = false - if err := hs.readFinished(nil); err != nil { - return err - } - } else { - // The client didn't include a session ticket, or it wasn't - // valid so we do a full handshake. - if err := hs.pickCipherSuite(); err != nil { - return err - } - if err := hs.doFullHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.readFinished(c.clientFinished[:]); err != nil { - return err - } - c.clientFinishedIsFirst = true - c.buffering = true - if err := hs.sendSessionTicket(); err != nil { - return err - } - if err := hs.sendFinished(nil); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - } - - c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random) - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -// readClientHello reads a ClientHello message and selects the protocol version. -func (c *Conn) readClientHello() (*clientHelloMsg, error) { - msg, err := c.readHandshake() - if err != nil { - return nil, err - } - clientHello, ok := msg.(*clientHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return nil, unexpectedMessageError(clientHello, msg) - } - - var configForClient *config - originalConfig := c.config - if c.config.GetConfigForClient != nil { - chi := newClientHelloInfo(c, clientHello) - if cfc, err := c.config.GetConfigForClient(chi); err != nil { - c.sendAlert(alertInternalError) - return nil, err - } else if cfc != nil { - configForClient = fromConfig(cfc) - c.config = configForClient - } - } - c.ticketKeys = originalConfig.ticketKeys(configForClient) - - clientVersions := clientHello.supportedVersions - if len(clientHello.supportedVersions) == 0 { - clientVersions = supportedVersionsFromMax(clientHello.vers) - } - if c.extraConfig.usesAlternativeRecordLayer() { - // In QUIC, the client MUST NOT offer any old TLS versions. - // Here, we can only check that none of the other supported versions of this library - // (TLS 1.0 - TLS 1.2) is offered. We don't check for any SSL versions here. - for _, ver := range clientVersions { - if ver == VersionTLS13 { - continue - } - for _, v := range supportedVersions { - if ver == v { - c.sendAlert(alertProtocolVersion) - return nil, fmt.Errorf("tls: client offered old TLS version %#x", ver) - } - } - } - // Make the config we're using allows us to use TLS 1.3. - if c.config.maxSupportedVersion() < VersionTLS13 { - c.sendAlert(alertInternalError) - return nil, errors.New("tls: MaxVersion prevents QUIC from using TLS 1.3") - } - } - c.vers, ok = c.config.mutualVersion(clientVersions) - if !ok { - c.sendAlert(alertProtocolVersion) - return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions) - } - c.haveVers = true - c.in.version = c.vers - c.out.version = c.vers - - return clientHello, nil -} - -func (hs *serverHandshakeState) processClientHello() error { - c := hs.c - - hs.hello = new(serverHelloMsg) - hs.hello.vers = c.vers - - foundCompression := false - // We only support null compression, so check that the client offered it. - for _, compression := range hs.clientHello.compressionMethods { - if compression == compressionNone { - foundCompression = true - break - } - } - - if !foundCompression { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: client does not support uncompressed connections") - } - - hs.hello.random = make([]byte, 32) - serverRandom := hs.hello.random - // Downgrade protection canaries. See RFC 8446, Section 4.1.3. - maxVers := c.config.maxSupportedVersion() - if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary { - if c.vers == VersionTLS12 { - copy(serverRandom[24:], downgradeCanaryTLS12) - } else { - copy(serverRandom[24:], downgradeCanaryTLS11) - } - serverRandom = serverRandom[:24] - } - _, err := io.ReadFull(c.config.rand(), serverRandom) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - if len(hs.clientHello.secureRenegotiation) != 0 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: initial handshake had non-empty renegotiation extension") - } - - hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported - hs.hello.compressionMethod = compressionNone - if len(hs.clientHello.serverName) > 0 { - c.serverName = hs.clientHello.serverName - } - - if len(hs.clientHello.alpnProtocols) > 0 { - if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" { - hs.hello.alpnProtocol = selectedProto - c.clientProtocol = selectedProto - } - } - - hs.cert, err = c.config.getCertificate(newClientHelloInfo(c, hs.clientHello)) - if err != nil { - if err == errNoCertificates { - c.sendAlert(alertUnrecognizedName) - } else { - c.sendAlert(alertInternalError) - } - return err - } - if hs.clientHello.scts { - hs.hello.scts = hs.cert.SignedCertificateTimestamps - } - - hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints) - - if hs.ecdheOk { - // Although omitting the ec_point_formats extension is permitted, some - // old OpenSSL version will refuse to handshake if not present. - // - // Per RFC 4492, section 5.1.2, implementations MUST support the - // uncompressed point format. See golang.org/issue/31943. - hs.hello.supportedPoints = []uint8{pointFormatUncompressed} - } - - if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok { - switch priv.Public().(type) { - case *ecdsa.PublicKey: - hs.ecSignOk = true - case ed25519.PublicKey: - hs.ecSignOk = true - case *rsa.PublicKey: - hs.rsaSignOk = true - default: - c.sendAlert(alertInternalError) - return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public()) - } - } - if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok { - switch priv.Public().(type) { - case *rsa.PublicKey: - hs.rsaDecryptOk = true - default: - c.sendAlert(alertInternalError) - return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public()) - } - } - - return nil -} - -// supportsECDHE returns whether ECDHE key exchanges can be used with this -// pre-TLS 1.3 client. -func supportsECDHE(c *config, supportedCurves []CurveID, supportedPoints []uint8) bool { - supportsCurve := false - for _, curve := range supportedCurves { - if c.supportsCurve(curve) { - supportsCurve = true - break - } - } - - supportsPointFormat := false - for _, pointFormat := range supportedPoints { - if pointFormat == pointFormatUncompressed { - supportsPointFormat = true - break - } - } - - return supportsCurve && supportsPointFormat -} - -func (hs *serverHandshakeState) pickCipherSuite() error { - c := hs.c - - var preferenceList, supportedList []uint16 - if c.config.PreferServerCipherSuites { - preferenceList = c.config.cipherSuites() - supportedList = hs.clientHello.cipherSuites - - // If the client does not seem to have hardware support for AES-GCM, - // and the application did not specify a cipher suite preference order, - // prefer other AEAD ciphers even if we prioritized AES-GCM ciphers - // by default. - if c.config.CipherSuites == nil && !aesgcmPreferred(hs.clientHello.cipherSuites) { - preferenceList = deprioritizeAES(preferenceList) - } - } else { - preferenceList = hs.clientHello.cipherSuites - supportedList = c.config.cipherSuites() - - // If we don't have hardware support for AES-GCM, prefer other AEAD - // ciphers even if the client prioritized AES-GCM. - if !hasAESGCMHardwareSupport { - preferenceList = deprioritizeAES(preferenceList) - } - } - - hs.suite = selectCipherSuite(preferenceList, supportedList, hs.cipherSuiteOk) - if hs.suite == nil { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: no cipher suite supported by both client and server") - } - c.cipherSuite = hs.suite.id - - for _, id := range hs.clientHello.cipherSuites { - if id == TLS_FALLBACK_SCSV { - // The client is doing a fallback connection. See RFC 7507. - if hs.clientHello.vers < c.config.maxSupportedVersion() { - c.sendAlert(alertInappropriateFallback) - return errors.New("tls: client using inappropriate protocol fallback") - } - break - } - } - - return nil -} - -func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool { - if c.flags&suiteECDHE != 0 { - if !hs.ecdheOk { - return false - } - if c.flags&suiteECSign != 0 { - if !hs.ecSignOk { - return false - } - } else if !hs.rsaSignOk { - return false - } - } else if !hs.rsaDecryptOk { - return false - } - if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { - return false - } - return true -} - -// checkForResumption reports whether we should perform resumption on this connection. -func (hs *serverHandshakeState) checkForResumption() bool { - c := hs.c - - if c.config.SessionTicketsDisabled { - return false - } - - plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket) - if plaintext == nil { - return false - } - hs.sessionState = &sessionState{usedOldKey: usedOldKey} - ok := hs.sessionState.unmarshal(plaintext) - if !ok { - return false - } - - createdAt := time.Unix(int64(hs.sessionState.createdAt), 0) - if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { - return false - } - - // Never resume a session for a different TLS version. - if c.vers != hs.sessionState.vers { - return false - } - - cipherSuiteOk := false - // Check that the client is still offering the ciphersuite in the session. - for _, id := range hs.clientHello.cipherSuites { - if id == hs.sessionState.cipherSuite { - cipherSuiteOk = true - break - } - } - if !cipherSuiteOk { - return false - } - - // Check that we also support the ciphersuite from the session. - hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite}, - c.config.cipherSuites(), hs.cipherSuiteOk) - if hs.suite == nil { - return false - } - - sessionHasClientCerts := len(hs.sessionState.certificates) != 0 - needClientCerts := requiresClientCert(c.config.ClientAuth) - if needClientCerts && !sessionHasClientCerts { - return false - } - if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { - return false - } - - return true -} - -func (hs *serverHandshakeState) doResumeHandshake() error { - c := hs.c - - hs.hello.cipherSuite = hs.suite.id - c.cipherSuite = hs.suite.id - // We echo the client's session ID in the ServerHello to let it know - // that we're doing a resumption. - hs.hello.sessionId = hs.clientHello.sessionId - hs.hello.ticketSupported = hs.sessionState.usedOldKey - hs.finishedHash = newFinishedHash(c.vers, hs.suite) - hs.finishedHash.discardHandshakeBuffer() - hs.finishedHash.Write(hs.clientHello.marshal()) - hs.finishedHash.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - if err := c.processCertsFromClient(Certificate{ - Certificate: hs.sessionState.certificates, - }); err != nil { - return err - } - - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - hs.masterSecret = hs.sessionState.masterSecret - - return nil -} - -func (hs *serverHandshakeState) doFullHandshake() error { - c := hs.c - - if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { - hs.hello.ocspStapling = true - } - - hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled - hs.hello.cipherSuite = hs.suite.id - - hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite) - if c.config.ClientAuth == NoClientCert { - // No need to keep a full record of the handshake if client - // certificates won't be used. - hs.finishedHash.discardHandshakeBuffer() - } - hs.finishedHash.Write(hs.clientHello.marshal()) - hs.finishedHash.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - certMsg := new(certificateMsg) - certMsg.certificates = hs.cert.Certificate - hs.finishedHash.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - - if hs.hello.ocspStapling { - certStatus := new(certificateStatusMsg) - certStatus.response = hs.cert.OCSPStaple - hs.finishedHash.Write(certStatus.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil { - return err - } - } - - keyAgreement := hs.suite.ka(c.vers) - skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - if skx != nil { - hs.finishedHash.Write(skx.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil { - return err - } - } - - var certReq *certificateRequestMsg - if c.config.ClientAuth >= RequestClientCert { - // Request a client certificate - certReq = new(certificateRequestMsg) - certReq.certificateTypes = []byte{ - byte(certTypeRSASign), - byte(certTypeECDSASign), - } - if c.vers >= VersionTLS12 { - certReq.hasSignatureAlgorithm = true - certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms - } - - // An empty list of certificateAuthorities signals to - // the client that it may send any certificate in response - // to our request. When we know the CAs we trust, then - // we can send them down, so that the client can choose - // an appropriate certificate to give to us. - if c.config.ClientCAs != nil { - certReq.certificateAuthorities = c.config.ClientCAs.Subjects() - } - hs.finishedHash.Write(certReq.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { - return err - } - } - - helloDone := new(serverHelloDoneMsg) - hs.finishedHash.Write(helloDone.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil { - return err - } - - if _, err := c.flush(); err != nil { - return err - } - - var pub crypto.PublicKey // public key for client auth, if any - - msg, err := c.readHandshake() - if err != nil { - return err - } - - // If we requested a client certificate, then the client must send a - // certificate message, even if it's empty. - if c.config.ClientAuth >= RequestClientCert { - certMsg, ok := msg.(*certificateMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - hs.finishedHash.Write(certMsg.marshal()) - - if err := c.processCertsFromClient(Certificate{ - Certificate: certMsg.certificates, - }); err != nil { - return err - } - if len(certMsg.certificates) != 0 { - pub = c.peerCertificates[0].PublicKey - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - // Get client key exchange - ckx, ok := msg.(*clientKeyExchangeMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(ckx, msg) - } - hs.finishedHash.Write(ckx.marshal()) - - preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random) - if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil { - c.sendAlert(alertInternalError) - return err - } - - // If we received a client cert in response to our certificate request message, - // the client will send us a certificateVerifyMsg immediately after the - // clientKeyExchangeMsg. This message is a digest of all preceding - // handshake-layer messages that is signed using the private key corresponding - // to the client's certificate. This allows us to verify that the client is in - // possession of the private key of the certificate. - if len(c.peerCertificates) > 0 { - msg, err = c.readHandshake() - if err != nil { - return err - } - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certVerify, msg) - } - - var sigType uint8 - var sigHash crypto.Hash - if c.vers >= VersionTLS12 { - if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client certificate used with invalid signature algorithm") - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub) - if err != nil { - c.sendAlert(alertIllegalParameter) - return err - } - } - - signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret) - if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid signature by the client certificate: " + err.Error()) - } - - hs.finishedHash.Write(certVerify.marshal()) - } - - hs.finishedHash.discardHandshakeBuffer() - - return nil -} - -func (hs *serverHandshakeState) establishKeys() error { - c := hs.c - - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) - - var clientCipher, serverCipher interface{} - var clientHash, serverHash hash.Hash - - if hs.suite.aead == nil { - clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) - clientHash = hs.suite.mac(clientMAC) - serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) - serverHash = hs.suite.mac(serverMAC) - } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) - } - - c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) - c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) - - return nil -} - -func (hs *serverHandshakeState) readFinished(out []byte) error { - c := hs.c - - if err := c.readChangeCipherSpec(); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - clientFinished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(clientFinished, msg) - } - - verify := hs.finishedHash.clientSum(hs.masterSecret) - if len(verify) != len(clientFinished.verifyData) || - subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: client's Finished message is incorrect") - } - - hs.finishedHash.Write(clientFinished.marshal()) - copy(out, verify) - return nil -} - -func (hs *serverHandshakeState) sendSessionTicket() error { - // ticketSupported is set in a resumption handshake if the - // ticket from the client was encrypted with an old session - // ticket key and thus a refreshed ticket should be sent. - if !hs.hello.ticketSupported { - return nil - } - - c := hs.c - m := new(newSessionTicketMsg) - - createdAt := uint64(c.config.time().Unix()) - if hs.sessionState != nil { - // If this is re-wrapping an old key, then keep - // the original time it was created. - createdAt = hs.sessionState.createdAt - } - - var certsFromClient [][]byte - for _, cert := range c.peerCertificates { - certsFromClient = append(certsFromClient, cert.Raw) - } - state := sessionState{ - vers: c.vers, - cipherSuite: hs.suite.id, - createdAt: createdAt, - masterSecret: hs.masterSecret, - certificates: certsFromClient, - } - var err error - m.ticket, err = c.encryptTicket(state.marshal()) - if err != nil { - return err - } - - hs.finishedHash.Write(m.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeState) sendFinished(out []byte) error { - c := hs.c - - if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { - return err - } - - finished := new(finishedMsg) - finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) - hs.finishedHash.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - - copy(out, finished.verifyData) - - return nil -} - -// processCertsFromClient takes a chain of client certificates either from a -// Certificates message or from a sessionState and verifies them. It returns -// the public key of the leaf certificate. -func (c *Conn) processCertsFromClient(certificate Certificate) error { - certificates := certificate.Certificate - certs := make([]*x509.Certificate, len(certificates)) - var err error - for i, asn1Data := range certificates { - if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to parse client certificate: " + err.Error()) - } - } - - if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) { - c.sendAlert(alertBadCertificate) - return errors.New("tls: client didn't provide a certificate") - } - - if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { - opts := x509.VerifyOptions{ - Roots: c.config.ClientCAs, - CurrentTime: c.config.time(), - Intermediates: x509.NewCertPool(), - KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, - } - - for _, cert := range certs[1:] { - opts.Intermediates.AddCert(cert) - } - - chains, err := certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to verify client certificate: " + err.Error()) - } - - c.verifiedChains = chains - } - - c.peerCertificates = certs - c.ocspResponse = certificate.OCSPStaple - c.scts = certificate.SignedCertificateTimestamps - - if len(certs) > 0 { - switch certs[0].PublicKey.(type) { - case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey: - default: - c.sendAlert(alertUnsupportedCertificate) - return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey) - } - } - - if c.config.VerifyPeerCertificate != nil { - if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - return nil -} - -func newClientHelloInfo(c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { - supportedVersions := clientHello.supportedVersions - if len(clientHello.supportedVersions) == 0 { - supportedVersions = supportedVersionsFromMax(clientHello.vers) - } - - return toClientHelloInfo(&clientHelloInfo{ - CipherSuites: clientHello.cipherSuites, - ServerName: clientHello.serverName, - SupportedCurves: clientHello.supportedCurves, - SupportedPoints: clientHello.supportedPoints, - SignatureSchemes: clientHello.supportedSignatureAlgorithms, - SupportedProtos: clientHello.alpnProtocols, - SupportedVersions: supportedVersions, - Conn: c.conn, - config: toConfig(c.config), - }) -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_server_tls13.go b/vendor/github.com/marten-seemann/qtls-go1-16/handshake_server_tls13.go deleted file mode 100644 index e1ab918d3..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/handshake_server_tls13.go +++ /dev/null @@ -1,912 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "bytes" - "crypto" - "crypto/hmac" - "crypto/rsa" - "errors" - "fmt" - "hash" - "io" - "sync/atomic" - "time" -) - -// maxClientPSKIdentities is the number of client PSK identities the server will -// attempt to validate. It will ignore the rest not to let cheap ClientHello -// messages cause too much work in session ticket decryption attempts. -const maxClientPSKIdentities = 5 - -type serverHandshakeStateTLS13 struct { - c *Conn - clientHello *clientHelloMsg - hello *serverHelloMsg - encryptedExtensions *encryptedExtensionsMsg - sentDummyCCS bool - usingPSK bool - suite *cipherSuiteTLS13 - cert *Certificate - sigAlg SignatureScheme - earlySecret []byte - sharedKey []byte - handshakeSecret []byte - masterSecret []byte - trafficSecret []byte // client_application_traffic_secret_0 - transcript hash.Hash - clientFinished []byte -} - -func (hs *serverHandshakeStateTLS13) handshake() error { - c := hs.c - - // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2. - if err := hs.processClientHello(); err != nil { - return err - } - if err := hs.checkForResumption(); err != nil { - return err - } - if err := hs.pickCertificate(); err != nil { - return err - } - c.buffering = true - if err := hs.sendServerParameters(); err != nil { - return err - } - if err := hs.sendServerCertificate(); err != nil { - return err - } - if err := hs.sendServerFinished(); err != nil { - return err - } - // Note that at this point we could start sending application data without - // waiting for the client's second flight, but the application might not - // expect the lack of replay protection of the ClientHello parameters. - if _, err := c.flush(); err != nil { - return err - } - if err := hs.readClientCertificate(); err != nil { - return err - } - if err := hs.readClientFinished(); err != nil { - return err - } - - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -func (hs *serverHandshakeStateTLS13) processClientHello() error { - c := hs.c - - hs.hello = new(serverHelloMsg) - hs.encryptedExtensions = new(encryptedExtensionsMsg) - - // TLS 1.3 froze the ServerHello.legacy_version field, and uses - // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1. - hs.hello.vers = VersionTLS12 - hs.hello.supportedVersion = c.vers - - if len(hs.clientHello.supportedVersions) == 0 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client used the legacy version field to negotiate TLS 1.3") - } - - // Abort if the client is doing a fallback and landing lower than what we - // support. See RFC 7507, which however does not specify the interaction - // with supported_versions. The only difference is that with - // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4] - // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case, - // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to - // TLS 1.2, because a TLS 1.3 server would abort here. The situation before - // supported_versions was not better because there was just no way to do a - // TLS 1.4 handshake without risking the server selecting TLS 1.3. - for _, id := range hs.clientHello.cipherSuites { - if id == TLS_FALLBACK_SCSV { - // Use c.vers instead of max(supported_versions) because an attacker - // could defeat this by adding an arbitrary high version otherwise. - if c.vers < c.config.maxSupportedVersion() { - c.sendAlert(alertInappropriateFallback) - return errors.New("tls: client using inappropriate protocol fallback") - } - break - } - } - - if len(hs.clientHello.compressionMethods) != 1 || - hs.clientHello.compressionMethods[0] != compressionNone { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: TLS 1.3 client supports illegal compression methods") - } - - hs.hello.random = make([]byte, 32) - if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil { - c.sendAlert(alertInternalError) - return err - } - - if len(hs.clientHello.secureRenegotiation) != 0 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: initial handshake had non-empty renegotiation extension") - } - - hs.hello.sessionId = hs.clientHello.sessionId - hs.hello.compressionMethod = compressionNone - - var preferenceList, supportedList, ourList []uint16 - var useConfiguredCipherSuites bool - for _, suiteID := range c.config.CipherSuites { - for _, suite := range cipherSuitesTLS13 { - if suite.id == suiteID { - ourList = append(ourList, suiteID) - break - } - } - } - if len(ourList) > 0 { - useConfiguredCipherSuites = true - } else { - ourList = defaultCipherSuitesTLS13() - } - if c.config.PreferServerCipherSuites { - preferenceList = ourList - supportedList = hs.clientHello.cipherSuites - - // If the client does not seem to have hardware support for AES-GCM, - // prefer other AEAD ciphers even if we prioritized AES-GCM ciphers - // by default. - if !useConfiguredCipherSuites && !aesgcmPreferred(hs.clientHello.cipherSuites) { - preferenceList = deprioritizeAES(preferenceList) - } - } else { - preferenceList = hs.clientHello.cipherSuites - supportedList = ourList - - // If we don't have hardware support for AES-GCM, prefer other AEAD - // ciphers even if the client prioritized AES-GCM. - if !hasAESGCMHardwareSupport { - preferenceList = deprioritizeAES(preferenceList) - } - } - for _, suiteID := range preferenceList { - hs.suite = mutualCipherSuiteTLS13(supportedList, suiteID) - if hs.suite != nil { - break - } - } - if hs.suite == nil { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: no cipher suite supported by both client and server") - } - c.cipherSuite = hs.suite.id - hs.hello.cipherSuite = hs.suite.id - hs.transcript = hs.suite.hash.New() - - // Pick the ECDHE group in server preference order, but give priority to - // groups with a key share, to avoid a HelloRetryRequest round-trip. - var selectedGroup CurveID - var clientKeyShare *keyShare -GroupSelection: - for _, preferredGroup := range c.config.curvePreferences() { - for _, ks := range hs.clientHello.keyShares { - if ks.group == preferredGroup { - selectedGroup = ks.group - clientKeyShare = &ks - break GroupSelection - } - } - if selectedGroup != 0 { - continue - } - for _, group := range hs.clientHello.supportedCurves { - if group == preferredGroup { - selectedGroup = group - break - } - } - } - if selectedGroup == 0 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: no ECDHE curve supported by both client and server") - } - if clientKeyShare == nil { - if err := hs.doHelloRetryRequest(selectedGroup); err != nil { - return err - } - clientKeyShare = &hs.clientHello.keyShares[0] - } - - if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && !ok { - c.sendAlert(alertInternalError) - return errors.New("tls: CurvePreferences includes unsupported curve") - } - params, err := generateECDHEParameters(c.config.rand(), selectedGroup) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()} - hs.sharedKey = params.SharedKey(clientKeyShare.data) - if hs.sharedKey == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid client key share") - } - - c.serverName = hs.clientHello.serverName - - if c.extraConfig != nil && c.extraConfig.ReceivedExtensions != nil { - c.extraConfig.ReceivedExtensions(typeClientHello, hs.clientHello.additionalExtensions) - } - - if len(hs.clientHello.alpnProtocols) > 0 { - if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" { - hs.encryptedExtensions.alpnProtocol = selectedProto - c.clientProtocol = selectedProto - } - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) checkForResumption() error { - c := hs.c - - if c.config.SessionTicketsDisabled { - return nil - } - - modeOK := false - for _, mode := range hs.clientHello.pskModes { - if mode == pskModeDHE { - modeOK = true - break - } - } - if !modeOK { - return nil - } - - if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid or missing PSK binders") - } - if len(hs.clientHello.pskIdentities) == 0 { - return nil - } - - for i, identity := range hs.clientHello.pskIdentities { - if i >= maxClientPSKIdentities { - break - } - - plaintext, _ := c.decryptTicket(identity.label) - if plaintext == nil { - continue - } - sessionState := new(sessionStateTLS13) - if ok := sessionState.unmarshal(plaintext); !ok { - continue - } - - if hs.clientHello.earlyData { - if sessionState.maxEarlyData == 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: client sent unexpected early data") - } - - if sessionState.alpn == c.clientProtocol && - c.extraConfig != nil && c.extraConfig.MaxEarlyData > 0 && - c.extraConfig.Accept0RTT != nil && c.extraConfig.Accept0RTT(sessionState.appData) { - hs.encryptedExtensions.earlyData = true - c.used0RTT = true - } - } - - createdAt := time.Unix(int64(sessionState.createdAt), 0) - if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { - continue - } - - // We don't check the obfuscated ticket age because it's affected by - // clock skew and it's only a freshness signal useful for shrinking the - // window for replay attacks, which don't affect us as we don't do 0-RTT. - - pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite) - if pskSuite == nil || pskSuite.hash != hs.suite.hash { - continue - } - - // PSK connections don't re-establish client certificates, but carry - // them over in the session ticket. Ensure the presence of client certs - // in the ticket is consistent with the configured requirements. - sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0 - needClientCerts := requiresClientCert(c.config.ClientAuth) - if needClientCerts && !sessionHasClientCerts { - continue - } - if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { - continue - } - - psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption", - nil, hs.suite.hash.Size()) - hs.earlySecret = hs.suite.extract(psk, nil) - binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil) - // Clone the transcript in case a HelloRetryRequest was recorded. - transcript := cloneHash(hs.transcript, hs.suite.hash) - if transcript == nil { - c.sendAlert(alertInternalError) - return errors.New("tls: internal error: failed to clone hash") - } - transcript.Write(hs.clientHello.marshalWithoutBinders()) - pskBinder := hs.suite.finishedHash(binderKey, transcript) - if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid PSK binder") - } - - c.didResume = true - if err := c.processCertsFromClient(sessionState.certificate); err != nil { - return err - } - - h := cloneHash(hs.transcript, hs.suite.hash) - h.Write(hs.clientHello.marshal()) - if hs.encryptedExtensions.earlyData { - clientEarlySecret := hs.suite.deriveSecret(hs.earlySecret, "c e traffic", h) - c.in.exportKey(Encryption0RTT, hs.suite, clientEarlySecret) - if err := c.config.writeKeyLog(keyLogLabelEarlyTraffic, hs.clientHello.random, clientEarlySecret); err != nil { - c.sendAlert(alertInternalError) - return err - } - } - - hs.hello.selectedIdentityPresent = true - hs.hello.selectedIdentity = uint16(i) - hs.usingPSK = true - return nil - } - - return nil -} - -// cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler -// interfaces implemented by standard library hashes to clone the state of in -// to a new instance of h. It returns nil if the operation fails. -func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash { - // Recreate the interface to avoid importing encoding. - type binaryMarshaler interface { - MarshalBinary() (data []byte, err error) - UnmarshalBinary(data []byte) error - } - marshaler, ok := in.(binaryMarshaler) - if !ok { - return nil - } - state, err := marshaler.MarshalBinary() - if err != nil { - return nil - } - out := h.New() - unmarshaler, ok := out.(binaryMarshaler) - if !ok { - return nil - } - if err := unmarshaler.UnmarshalBinary(state); err != nil { - return nil - } - return out -} - -func (hs *serverHandshakeStateTLS13) pickCertificate() error { - c := hs.c - - // Only one of PSK and certificates are used at a time. - if hs.usingPSK { - return nil - } - - // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3. - if len(hs.clientHello.supportedSignatureAlgorithms) == 0 { - return c.sendAlert(alertMissingExtension) - } - - certificate, err := c.config.getCertificate(newClientHelloInfo(c, hs.clientHello)) - if err != nil { - if err == errNoCertificates { - c.sendAlert(alertUnrecognizedName) - } else { - c.sendAlert(alertInternalError) - } - return err - } - hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms) - if err != nil { - // getCertificate returned a certificate that is unsupported or - // incompatible with the client's signature algorithms. - c.sendAlert(alertHandshakeFailure) - return err - } - hs.cert = certificate - - return nil -} - -// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility -// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. -func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error { - if hs.sentDummyCCS { - return nil - } - hs.sentDummyCCS = true - - _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - return err -} - -func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error { - c := hs.c - - // The first ClientHello gets double-hashed into the transcript upon a - // HelloRetryRequest. See RFC 8446, Section 4.4.1. - hs.transcript.Write(hs.clientHello.marshal()) - chHash := hs.transcript.Sum(nil) - hs.transcript.Reset() - hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) - hs.transcript.Write(chHash) - - helloRetryRequest := &serverHelloMsg{ - vers: hs.hello.vers, - random: helloRetryRequestRandom, - sessionId: hs.hello.sessionId, - cipherSuite: hs.hello.cipherSuite, - compressionMethod: hs.hello.compressionMethod, - supportedVersion: hs.hello.supportedVersion, - selectedGroup: selectedGroup, - } - - hs.transcript.Write(helloRetryRequest.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil { - return err - } - - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - clientHello, ok := msg.(*clientHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(clientHello, msg) - } - - if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client sent invalid key share in second ClientHello") - } - - if clientHello.earlyData { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client indicated early data in second ClientHello") - } - - if illegalClientHelloChange(clientHello, hs.clientHello) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client illegally modified second ClientHello") - } - - if clientHello.earlyData { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client offered 0-RTT data in second ClientHello") - } - - hs.clientHello = clientHello - return nil -} - -// illegalClientHelloChange reports whether the two ClientHello messages are -// different, with the exception of the changes allowed before and after a -// HelloRetryRequest. See RFC 8446, Section 4.1.2. -func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { - if len(ch.supportedVersions) != len(ch1.supportedVersions) || - len(ch.cipherSuites) != len(ch1.cipherSuites) || - len(ch.supportedCurves) != len(ch1.supportedCurves) || - len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) || - len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) || - len(ch.alpnProtocols) != len(ch1.alpnProtocols) { - return true - } - for i := range ch.supportedVersions { - if ch.supportedVersions[i] != ch1.supportedVersions[i] { - return true - } - } - for i := range ch.cipherSuites { - if ch.cipherSuites[i] != ch1.cipherSuites[i] { - return true - } - } - for i := range ch.supportedCurves { - if ch.supportedCurves[i] != ch1.supportedCurves[i] { - return true - } - } - for i := range ch.supportedSignatureAlgorithms { - if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] { - return true - } - } - for i := range ch.supportedSignatureAlgorithmsCert { - if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] { - return true - } - } - for i := range ch.alpnProtocols { - if ch.alpnProtocols[i] != ch1.alpnProtocols[i] { - return true - } - } - return ch.vers != ch1.vers || - !bytes.Equal(ch.random, ch1.random) || - !bytes.Equal(ch.sessionId, ch1.sessionId) || - !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || - ch.serverName != ch1.serverName || - ch.ocspStapling != ch1.ocspStapling || - !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || - ch.ticketSupported != ch1.ticketSupported || - !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) || - ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported || - !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) || - ch.scts != ch1.scts || - !bytes.Equal(ch.cookie, ch1.cookie) || - !bytes.Equal(ch.pskModes, ch1.pskModes) -} - -func (hs *serverHandshakeStateTLS13) sendServerParameters() error { - c := hs.c - - if c.extraConfig != nil && c.extraConfig.EnforceNextProtoSelection && len(c.clientProtocol) == 0 { - c.sendAlert(alertNoApplicationProtocol) - return fmt.Errorf("ALPN negotiation failed. Client offered: %q", hs.clientHello.alpnProtocols) - } - - hs.transcript.Write(hs.clientHello.marshal()) - hs.transcript.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - - earlySecret := hs.earlySecret - if earlySecret == nil { - earlySecret = hs.suite.extract(nil, nil) - } - hs.handshakeSecret = hs.suite.extract(hs.sharedKey, - hs.suite.deriveSecret(earlySecret, "derived", nil)) - - clientSecret := hs.suite.deriveSecret(hs.handshakeSecret, - clientHandshakeTrafficLabel, hs.transcript) - c.in.exportKey(EncryptionHandshake, hs.suite, clientSecret) - c.in.setTrafficSecret(hs.suite, clientSecret) - serverSecret := hs.suite.deriveSecret(hs.handshakeSecret, - serverHandshakeTrafficLabel, hs.transcript) - c.out.exportKey(EncryptionHandshake, hs.suite, serverSecret) - c.out.setTrafficSecret(hs.suite, serverSecret) - - err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - if hs.c.extraConfig != nil && hs.c.extraConfig.GetExtensions != nil { - hs.encryptedExtensions.additionalExtensions = hs.c.extraConfig.GetExtensions(typeEncryptedExtensions) - } - - hs.transcript.Write(hs.encryptedExtensions.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.encryptedExtensions.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) requestClientCert() bool { - return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK -} - -func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { - c := hs.c - - // Only one of PSK and certificates are used at a time. - if hs.usingPSK { - return nil - } - - if hs.requestClientCert() { - // Request a client certificate - certReq := new(certificateRequestMsgTLS13) - certReq.ocspStapling = true - certReq.scts = true - certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms - if c.config.ClientCAs != nil { - certReq.certificateAuthorities = c.config.ClientCAs.Subjects() - } - - hs.transcript.Write(certReq.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { - return err - } - } - - certMsg := new(certificateMsgTLS13) - - certMsg.certificate = *hs.cert - certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0 - certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 - - hs.transcript.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - - certVerifyMsg := new(certificateVerifyMsg) - certVerifyMsg.hasSignatureAlgorithm = true - certVerifyMsg.signatureAlgorithm = hs.sigAlg - - sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg) - if err != nil { - return c.sendAlert(alertInternalError) - } - - signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) - if err != nil { - public := hs.cert.PrivateKey.(crypto.Signer).Public() - if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS && - rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS - c.sendAlert(alertHandshakeFailure) - } else { - c.sendAlert(alertInternalError) - } - return errors.New("tls: failed to sign handshake: " + err.Error()) - } - certVerifyMsg.signature = sig - - hs.transcript.Write(certVerifyMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) sendServerFinished() error { - c := hs.c - - finished := &finishedMsg{ - verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), - } - - hs.transcript.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - - // Derive secrets that take context through the server Finished. - - hs.masterSecret = hs.suite.extract(nil, - hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil)) - - hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, - clientApplicationTrafficLabel, hs.transcript) - serverSecret := hs.suite.deriveSecret(hs.masterSecret, - serverApplicationTrafficLabel, hs.transcript) - c.out.exportKey(EncryptionApplication, hs.suite, serverSecret) - c.out.setTrafficSecret(hs.suite, serverSecret) - - err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) - - // If we did not request client certificates, at this point we can - // precompute the client finished and roll the transcript forward to send - // session tickets in our first flight. - if !hs.requestClientCert() { - if err := hs.sendSessionTickets(); err != nil { - return err - } - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool { - if hs.c.config.SessionTicketsDisabled { - return false - } - - // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9. - for _, pskMode := range hs.clientHello.pskModes { - if pskMode == pskModeDHE { - return true - } - } - return false -} - -func (hs *serverHandshakeStateTLS13) sendSessionTickets() error { - c := hs.c - - hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) - finishedMsg := &finishedMsg{ - verifyData: hs.clientFinished, - } - hs.transcript.Write(finishedMsg.marshal()) - - if !hs.shouldSendSessionTickets() { - return nil - } - - c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, - resumptionLabel, hs.transcript) - - // Don't send session tickets when the alternative record layer is set. - // Instead, save the resumption secret on the Conn. - // Session tickets can then be generated by calling Conn.GetSessionTicket(). - if hs.c.extraConfig != nil && hs.c.extraConfig.AlternativeRecordLayer != nil { - return nil - } - - m, err := hs.c.getSessionTicketMsg(nil) - if err != nil { - return err - } - if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) readClientCertificate() error { - c := hs.c - - if !hs.requestClientCert() { - // Make sure the connection is still being verified whether or not - // the server requested a client certificate. - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - return nil - } - - // If we requested a client certificate, then the client must send a - // certificate message. If it's empty, no CertificateVerify is sent. - - msg, err := c.readHandshake() - if err != nil { - return err - } - - certMsg, ok := msg.(*certificateMsgTLS13) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - hs.transcript.Write(certMsg.marshal()) - - if err := c.processCertsFromClient(certMsg.certificate); err != nil { - return err - } - - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - if len(certMsg.certificate.Certificate) != 0 { - msg, err = c.readHandshake() - if err != nil { - return err - } - - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certVerify, msg) - } - - // See RFC 8446, Section 4.4.3. - if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client certificate used with invalid signature algorithm") - } - sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client certificate used with invalid signature algorithm") - } - signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) - if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, - sigHash, signed, certVerify.signature); err != nil { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid signature by the client certificate: " + err.Error()) - } - - hs.transcript.Write(certVerify.marshal()) - } - - // If we waited until the client certificates to send session tickets, we - // are ready to do it now. - if err := hs.sendSessionTickets(); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) readClientFinished() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - - finished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(finished, msg) - } - - if !hmac.Equal(hs.clientFinished, finished.verifyData) { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid client finished hash") - } - - c.in.exportKey(EncryptionApplication, hs.suite, hs.trafficSecret) - c.in.setTrafficSecret(hs.suite, hs.trafficSecret) - - return nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/key_agreement.go b/vendor/github.com/marten-seemann/qtls-go1-16/key_agreement.go deleted file mode 100644 index d8f5d4690..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/key_agreement.go +++ /dev/null @@ -1,338 +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 qtls - -import ( - "crypto" - "crypto/md5" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "errors" - "fmt" - "io" -) - -var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") -var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") - -// rsaKeyAgreement implements the standard TLS key agreement where the client -// encrypts the pre-master secret to the server's public key. -type rsaKeyAgreement struct{} - -func (ka rsaKeyAgreement) generateServerKeyExchange(config *config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - return nil, nil -} - -func (ka rsaKeyAgreement) processClientKeyExchange(config *config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - if len(ckx.ciphertext) < 2 { - return nil, errClientKeyExchange - } - ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) - if ciphertextLen != len(ckx.ciphertext)-2 { - return nil, errClientKeyExchange - } - ciphertext := ckx.ciphertext[2:] - - priv, ok := cert.PrivateKey.(crypto.Decrypter) - if !ok { - return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") - } - // Perform constant time RSA PKCS #1 v1.5 decryption - preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48}) - if err != nil { - return nil, err - } - // We don't check the version number in the premaster secret. For one, - // by checking it, we would leak information about the validity of the - // encrypted pre-master secret. Secondly, it provides only a small - // benefit against a downgrade attack and some implementations send the - // wrong version anyway. See the discussion at the end of section - // 7.4.7.1 of RFC 4346. - return preMasterSecret, nil -} - -func (ka rsaKeyAgreement) processServerKeyExchange(config *config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - return errors.New("tls: unexpected ServerKeyExchange") -} - -func (ka rsaKeyAgreement) generateClientKeyExchange(config *config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - preMasterSecret := make([]byte, 48) - preMasterSecret[0] = byte(clientHello.vers >> 8) - preMasterSecret[1] = byte(clientHello.vers) - _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) - if err != nil { - return nil, nil, err - } - - rsaKey, ok := cert.PublicKey.(*rsa.PublicKey) - if !ok { - return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite") - } - encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret) - if err != nil { - return nil, nil, err - } - ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, len(encrypted)+2) - ckx.ciphertext[0] = byte(len(encrypted) >> 8) - ckx.ciphertext[1] = byte(len(encrypted)) - copy(ckx.ciphertext[2:], encrypted) - return preMasterSecret, ckx, nil -} - -// sha1Hash calculates a SHA1 hash over the given byte slices. -func sha1Hash(slices [][]byte) []byte { - hsha1 := sha1.New() - for _, slice := range slices { - hsha1.Write(slice) - } - return hsha1.Sum(nil) -} - -// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the -// concatenation of an MD5 and SHA1 hash. -func md5SHA1Hash(slices [][]byte) []byte { - md5sha1 := make([]byte, md5.Size+sha1.Size) - hmd5 := md5.New() - for _, slice := range slices { - hmd5.Write(slice) - } - copy(md5sha1, hmd5.Sum(nil)) - copy(md5sha1[md5.Size:], sha1Hash(slices)) - return md5sha1 -} - -// hashForServerKeyExchange hashes the given slices and returns their digest -// using the given hash function (for >= TLS 1.2) or using a default based on -// the sigType (for earlier TLS versions). For Ed25519 signatures, which don't -// do pre-hashing, it returns the concatenation of the slices. -func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte { - if sigType == signatureEd25519 { - var signed []byte - for _, slice := range slices { - signed = append(signed, slice...) - } - return signed - } - if version >= VersionTLS12 { - h := hashFunc.New() - for _, slice := range slices { - h.Write(slice) - } - digest := h.Sum(nil) - return digest - } - if sigType == signatureECDSA { - return sha1Hash(slices) - } - return md5SHA1Hash(slices) -} - -// ecdheKeyAgreement implements a TLS key agreement where the server -// generates an ephemeral EC public/private key pair and signs it. The -// pre-master secret is then calculated using ECDH. The signature may -// be ECDSA, Ed25519 or RSA. -type ecdheKeyAgreement struct { - version uint16 - isRSA bool - params ecdheParameters - - // ckx and preMasterSecret are generated in processServerKeyExchange - // and returned in generateClientKeyExchange. - ckx *clientKeyExchangeMsg - preMasterSecret []byte -} - -func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - var curveID CurveID - for _, c := range clientHello.supportedCurves { - if config.supportsCurve(c) { - curveID = c - break - } - } - - if curveID == 0 { - return nil, errors.New("tls: no supported elliptic curves offered") - } - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - return nil, errors.New("tls: CurvePreferences includes unsupported curve") - } - - params, err := generateECDHEParameters(config.rand(), curveID) - if err != nil { - return nil, err - } - ka.params = params - - // See RFC 4492, Section 5.4. - ecdhePublic := params.PublicKey() - serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic)) - serverECDHEParams[0] = 3 // named curve - serverECDHEParams[1] = byte(curveID >> 8) - serverECDHEParams[2] = byte(curveID) - serverECDHEParams[3] = byte(len(ecdhePublic)) - copy(serverECDHEParams[4:], ecdhePublic) - - priv, ok := cert.PrivateKey.(crypto.Signer) - if !ok { - return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey) - } - - var signatureAlgorithm SignatureScheme - var sigType uint8 - var sigHash crypto.Hash - if ka.version >= VersionTLS12 { - signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms) - if err != nil { - return nil, err - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) - if err != nil { - return nil, err - } - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public()) - if err != nil { - return nil, err - } - } - if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { - return nil, errors.New("tls: certificate cannot be used with the selected cipher suite") - } - - signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams) - - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - sig, err := priv.Sign(config.rand(), signed, signOpts) - if err != nil { - return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error()) - } - - skx := new(serverKeyExchangeMsg) - sigAndHashLen := 0 - if ka.version >= VersionTLS12 { - sigAndHashLen = 2 - } - skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig)) - copy(skx.key, serverECDHEParams) - k := skx.key[len(serverECDHEParams):] - if ka.version >= VersionTLS12 { - k[0] = byte(signatureAlgorithm >> 8) - k[1] = byte(signatureAlgorithm) - k = k[2:] - } - k[0] = byte(len(sig) >> 8) - k[1] = byte(len(sig)) - copy(k[2:], sig) - - return skx, nil -} - -func (ka *ecdheKeyAgreement) processClientKeyExchange(config *config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { - return nil, errClientKeyExchange - } - - preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:]) - if preMasterSecret == nil { - return nil, errClientKeyExchange - } - - return preMasterSecret, nil -} - -func (ka *ecdheKeyAgreement) processServerKeyExchange(config *config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - if len(skx.key) < 4 { - return errServerKeyExchange - } - if skx.key[0] != 3 { // named curve - return errors.New("tls: server selected unsupported curve") - } - curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) - - publicLen := int(skx.key[3]) - if publicLen+4 > len(skx.key) { - return errServerKeyExchange - } - serverECDHEParams := skx.key[:4+publicLen] - publicKey := serverECDHEParams[4:] - - sig := skx.key[4+publicLen:] - if len(sig) < 2 { - return errServerKeyExchange - } - - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - return errors.New("tls: server selected unsupported curve") - } - - params, err := generateECDHEParameters(config.rand(), curveID) - if err != nil { - return err - } - ka.params = params - - ka.preMasterSecret = params.SharedKey(publicKey) - if ka.preMasterSecret == nil { - return errServerKeyExchange - } - - ourPublicKey := params.PublicKey() - ka.ckx = new(clientKeyExchangeMsg) - ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey)) - ka.ckx.ciphertext[0] = byte(len(ourPublicKey)) - copy(ka.ckx.ciphertext[1:], ourPublicKey) - - var sigType uint8 - var sigHash crypto.Hash - if ka.version >= VersionTLS12 { - signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1]) - sig = sig[2:] - if len(sig) < 2 { - return errServerKeyExchange - } - - if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) { - return errors.New("tls: certificate used with invalid signature algorithm") - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) - if err != nil { - return err - } - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey) - if err != nil { - return err - } - } - if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { - return errServerKeyExchange - } - - sigLen := int(sig[0])<<8 | int(sig[1]) - if sigLen+2 != len(sig) { - return errServerKeyExchange - } - sig = sig[2:] - - signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams) - if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil { - return errors.New("tls: invalid signature by the server certificate: " + err.Error()) - } - return nil -} - -func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - if ka.ckx == nil { - return nil, nil, errors.New("tls: missing ServerKeyExchange message") - } - - return ka.preMasterSecret, ka.ckx, nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/key_schedule.go b/vendor/github.com/marten-seemann/qtls-go1-16/key_schedule.go deleted file mode 100644 index da13904a6..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/key_schedule.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "crypto/elliptic" - "crypto/hmac" - "errors" - "hash" - "io" - "math/big" - - "golang.org/x/crypto/cryptobyte" - "golang.org/x/crypto/curve25519" - "golang.org/x/crypto/hkdf" -) - -// This file contains the functions necessary to compute the TLS 1.3 key -// schedule. See RFC 8446, Section 7. - -const ( - resumptionBinderLabel = "res binder" - clientHandshakeTrafficLabel = "c hs traffic" - serverHandshakeTrafficLabel = "s hs traffic" - clientApplicationTrafficLabel = "c ap traffic" - serverApplicationTrafficLabel = "s ap traffic" - exporterLabel = "exp master" - resumptionLabel = "res master" - trafficUpdateLabel = "traffic upd" -) - -// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1. -func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte { - var hkdfLabel cryptobyte.Builder - hkdfLabel.AddUint16(uint16(length)) - hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte("tls13 ")) - b.AddBytes([]byte(label)) - }) - hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(context) - }) - out := make([]byte, length) - n, err := hkdf.Expand(c.hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out) - if err != nil || n != length { - panic("tls: HKDF-Expand-Label invocation failed unexpectedly") - } - return out -} - -// deriveSecret implements Derive-Secret from RFC 8446, Section 7.1. -func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte { - if transcript == nil { - transcript = c.hash.New() - } - return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size()) -} - -// extract implements HKDF-Extract with the cipher suite hash. -func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte { - if newSecret == nil { - newSecret = make([]byte, c.hash.Size()) - } - return hkdf.Extract(c.hash.New, newSecret, currentSecret) -} - -// nextTrafficSecret generates the next traffic secret, given the current one, -// according to RFC 8446, Section 7.2. -func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte { - return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size()) -} - -// trafficKey generates traffic keys according to RFC 8446, Section 7.3. -func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) { - key = c.expandLabel(trafficSecret, "key", nil, c.keyLen) - iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength) - return -} - -// finishedHash generates the Finished verify_data or PskBinderEntry according -// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey -// selection. -func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte { - finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size()) - verifyData := hmac.New(c.hash.New, finishedKey) - verifyData.Write(transcript.Sum(nil)) - return verifyData.Sum(nil) -} - -// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to -// RFC 8446, Section 7.5. -func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) { - expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript) - return func(label string, context []byte, length int) ([]byte, error) { - secret := c.deriveSecret(expMasterSecret, label, nil) - h := c.hash.New() - h.Write(context) - return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil - } -} - -// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519, -// according to RFC 8446, Section 4.2.8.2. -type ecdheParameters interface { - CurveID() CurveID - PublicKey() []byte - SharedKey(peerPublicKey []byte) []byte -} - -func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) { - if curveID == X25519 { - privateKey := make([]byte, curve25519.ScalarSize) - if _, err := io.ReadFull(rand, privateKey); err != nil { - return nil, err - } - publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint) - if err != nil { - return nil, err - } - return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil - } - - curve, ok := curveForCurveID(curveID) - if !ok { - return nil, errors.New("tls: internal error: unsupported curve") - } - - p := &nistParameters{curveID: curveID} - var err error - p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand) - if err != nil { - return nil, err - } - return p, nil -} - -func curveForCurveID(id CurveID) (elliptic.Curve, bool) { - switch id { - case CurveP256: - return elliptic.P256(), true - case CurveP384: - return elliptic.P384(), true - case CurveP521: - return elliptic.P521(), true - default: - return nil, false - } -} - -type nistParameters struct { - privateKey []byte - x, y *big.Int // public key - curveID CurveID -} - -func (p *nistParameters) CurveID() CurveID { - return p.curveID -} - -func (p *nistParameters) PublicKey() []byte { - curve, _ := curveForCurveID(p.curveID) - return elliptic.Marshal(curve, p.x, p.y) -} - -func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte { - curve, _ := curveForCurveID(p.curveID) - // Unmarshal also checks whether the given point is on the curve. - x, y := elliptic.Unmarshal(curve, peerPublicKey) - if x == nil { - return nil - } - - xShared, _ := curve.ScalarMult(x, y, p.privateKey) - sharedKey := make([]byte, (curve.Params().BitSize+7)/8) - return xShared.FillBytes(sharedKey) -} - -type x25519Parameters struct { - privateKey []byte - publicKey []byte -} - -func (p *x25519Parameters) CurveID() CurveID { - return X25519 -} - -func (p *x25519Parameters) PublicKey() []byte { - return p.publicKey[:] -} - -func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte { - sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey) - if err != nil { - return nil - } - return sharedKey -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/prf.go b/vendor/github.com/marten-seemann/qtls-go1-16/prf.go deleted file mode 100644 index 9eb0221a0..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/prf.go +++ /dev/null @@ -1,283 +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 qtls - -import ( - "crypto" - "crypto/hmac" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "errors" - "fmt" - "hash" -) - -// Split a premaster secret in two as specified in RFC 4346, Section 5. -func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { - s1 = secret[0 : (len(secret)+1)/2] - s2 = secret[len(secret)/2:] - return -} - -// pHash implements the P_hash function, as defined in RFC 4346, Section 5. -func pHash(result, secret, seed []byte, hash func() hash.Hash) { - h := hmac.New(hash, secret) - h.Write(seed) - a := h.Sum(nil) - - j := 0 - for j < len(result) { - h.Reset() - h.Write(a) - h.Write(seed) - b := h.Sum(nil) - copy(result[j:], b) - j += len(b) - - h.Reset() - h.Write(a) - a = h.Sum(nil) - } -} - -// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5. -func prf10(result, secret, label, seed []byte) { - hashSHA1 := sha1.New - hashMD5 := md5.New - - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - s1, s2 := splitPreMasterSecret(secret) - pHash(result, s1, labelAndSeed, hashMD5) - result2 := make([]byte, len(result)) - pHash(result2, s2, labelAndSeed, hashSHA1) - - for i, b := range result2 { - result[i] ^= b - } -} - -// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5. -func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { - return func(result, secret, label, seed []byte) { - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - pHash(result, secret, labelAndSeed, hashFunc) - } -} - -const ( - masterSecretLength = 48 // Length of a master secret in TLS 1.1. - finishedVerifyLength = 12 // Length of verify_data in a Finished message. -) - -var masterSecretLabel = []byte("master secret") -var keyExpansionLabel = []byte("key expansion") -var clientFinishedLabel = []byte("client finished") -var serverFinishedLabel = []byte("server finished") - -func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { - switch version { - case VersionTLS10, VersionTLS11: - return prf10, crypto.Hash(0) - case VersionTLS12: - if suite.flags&suiteSHA384 != 0 { - return prf12(sha512.New384), crypto.SHA384 - } - return prf12(sha256.New), crypto.SHA256 - default: - panic("unknown version") - } -} - -func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { - prf, _ := prfAndHashForVersion(version, suite) - return prf -} - -// masterFromPreMasterSecret generates the master secret from the pre-master -// secret. See RFC 5246, Section 8.1. -func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { - seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) - seed = append(seed, clientRandom...) - seed = append(seed, serverRandom...) - - masterSecret := make([]byte, masterSecretLength) - prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed) - return masterSecret -} - -// keysFromMasterSecret generates the connection keys from the master -// secret, given the lengths of the MAC key, cipher key and IV, as defined in -// RFC 2246, Section 6.3. -func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { - seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) - seed = append(seed, serverRandom...) - seed = append(seed, clientRandom...) - - n := 2*macLen + 2*keyLen + 2*ivLen - keyMaterial := make([]byte, n) - prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed) - clientMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - serverMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - clientKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - serverKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - clientIV = keyMaterial[:ivLen] - keyMaterial = keyMaterial[ivLen:] - serverIV = keyMaterial[:ivLen] - return -} - -func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash { - var buffer []byte - if version >= VersionTLS12 { - buffer = []byte{} - } - - prf, hash := prfAndHashForVersion(version, cipherSuite) - if hash != 0 { - return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf} - } - - return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf} -} - -// A finishedHash calculates the hash of a set of handshake messages suitable -// for including in a Finished message. -type finishedHash struct { - client hash.Hash - server hash.Hash - - // Prior to TLS 1.2, an additional MD5 hash is required. - clientMD5 hash.Hash - serverMD5 hash.Hash - - // In TLS 1.2, a full buffer is sadly required. - buffer []byte - - version uint16 - prf func(result, secret, label, seed []byte) -} - -func (h *finishedHash) Write(msg []byte) (n int, err error) { - h.client.Write(msg) - h.server.Write(msg) - - if h.version < VersionTLS12 { - h.clientMD5.Write(msg) - h.serverMD5.Write(msg) - } - - if h.buffer != nil { - h.buffer = append(h.buffer, msg...) - } - - return len(msg), nil -} - -func (h finishedHash) Sum() []byte { - if h.version >= VersionTLS12 { - return h.client.Sum(nil) - } - - out := make([]byte, 0, md5.Size+sha1.Size) - out = h.clientMD5.Sum(out) - return h.client.Sum(out) -} - -// clientSum returns the contents of the verify_data member of a client's -// Finished message. -func (h finishedHash) clientSum(masterSecret []byte) []byte { - out := make([]byte, finishedVerifyLength) - h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) - return out -} - -// serverSum returns the contents of the verify_data member of a server's -// Finished message. -func (h finishedHash) serverSum(masterSecret []byte) []byte { - out := make([]byte, finishedVerifyLength) - h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) - return out -} - -// hashForClientCertificate returns the handshake messages so far, pre-hashed if -// necessary, suitable for signing by a TLS client certificate. -func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) []byte { - if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil { - panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer") - } - - if sigType == signatureEd25519 { - return h.buffer - } - - if h.version >= VersionTLS12 { - hash := hashAlg.New() - hash.Write(h.buffer) - return hash.Sum(nil) - } - - if sigType == signatureECDSA { - return h.server.Sum(nil) - } - - return h.Sum() -} - -// discardHandshakeBuffer is called when there is no more need to -// buffer the entirety of the handshake messages. -func (h *finishedHash) discardHandshakeBuffer() { - h.buffer = nil -} - -// noExportedKeyingMaterial is used as a value of -// ConnectionState.ekm when renegotiation is enabled and thus -// we wish to fail all key-material export requests. -func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) { - return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled") -} - -// ekmFromMasterSecret generates exported keying material as defined in RFC 5705. -func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) { - return func(label string, context []byte, length int) ([]byte, error) { - switch label { - case "client finished", "server finished", "master secret", "key expansion": - // These values are reserved and may not be used. - return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label) - } - - seedLen := len(serverRandom) + len(clientRandom) - if context != nil { - seedLen += 2 + len(context) - } - seed := make([]byte, 0, seedLen) - - seed = append(seed, clientRandom...) - seed = append(seed, serverRandom...) - - if context != nil { - if len(context) >= 1<<16 { - return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long") - } - seed = append(seed, byte(len(context)>>8), byte(len(context))) - seed = append(seed, context...) - } - - keyMaterial := make([]byte, length) - prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) - return keyMaterial, nil - } -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/ticket.go b/vendor/github.com/marten-seemann/qtls-go1-16/ticket.go deleted file mode 100644 index 006b8c1de..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/ticket.go +++ /dev/null @@ -1,259 +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 qtls - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/sha256" - "crypto/subtle" - "errors" - "io" - "time" - - "golang.org/x/crypto/cryptobyte" -) - -// sessionState contains the information that is serialized into a session -// ticket in order to later resume a connection. -type sessionState struct { - vers uint16 - cipherSuite uint16 - createdAt uint64 - masterSecret []byte // opaque master_secret<1..2^16-1>; - // struct { opaque certificate<1..2^24-1> } Certificate; - certificates [][]byte // Certificate certificate_list<0..2^24-1>; - - // usedOldKey is true if the ticket from which this session came from - // was encrypted with an older key and thus should be refreshed. - usedOldKey bool -} - -func (m *sessionState) marshal() []byte { - var b cryptobyte.Builder - b.AddUint16(m.vers) - b.AddUint16(m.cipherSuite) - addUint64(&b, m.createdAt) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.masterSecret) - }) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - for _, cert := range m.certificates { - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(cert) - }) - } - }) - return b.BytesOrPanic() -} - -func (m *sessionState) unmarshal(data []byte) bool { - *m = sessionState{usedOldKey: m.usedOldKey} - s := cryptobyte.String(data) - if ok := s.ReadUint16(&m.vers) && - s.ReadUint16(&m.cipherSuite) && - readUint64(&s, &m.createdAt) && - readUint16LengthPrefixed(&s, &m.masterSecret) && - len(m.masterSecret) != 0; !ok { - return false - } - var certList cryptobyte.String - if !s.ReadUint24LengthPrefixed(&certList) { - return false - } - for !certList.Empty() { - var cert []byte - if !readUint24LengthPrefixed(&certList, &cert) { - return false - } - m.certificates = append(m.certificates, cert) - } - return s.Empty() -} - -// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first -// version (revision = 0) doesn't carry any of the information needed for 0-RTT -// validation and the nonce is always empty. -// version (revision = 1) carries the max_early_data_size sent in the ticket. -// version (revision = 2) carries the ALPN sent in the ticket. -type sessionStateTLS13 struct { - // uint8 version = 0x0304; - // uint8 revision = 2; - cipherSuite uint16 - createdAt uint64 - resumptionSecret []byte // opaque resumption_master_secret<1..2^8-1>; - certificate Certificate // CertificateEntry certificate_list<0..2^24-1>; - maxEarlyData uint32 - alpn string - - appData []byte -} - -func (m *sessionStateTLS13) marshal() []byte { - var b cryptobyte.Builder - b.AddUint16(VersionTLS13) - b.AddUint8(2) // revision - b.AddUint16(m.cipherSuite) - addUint64(&b, m.createdAt) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.resumptionSecret) - }) - marshalCertificate(&b, m.certificate) - b.AddUint32(m.maxEarlyData) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.alpn)) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.appData) - }) - return b.BytesOrPanic() -} - -func (m *sessionStateTLS13) unmarshal(data []byte) bool { - *m = sessionStateTLS13{} - s := cryptobyte.String(data) - var version uint16 - var revision uint8 - var alpn []byte - ret := s.ReadUint16(&version) && - version == VersionTLS13 && - s.ReadUint8(&revision) && - revision == 2 && - s.ReadUint16(&m.cipherSuite) && - readUint64(&s, &m.createdAt) && - readUint8LengthPrefixed(&s, &m.resumptionSecret) && - len(m.resumptionSecret) != 0 && - unmarshalCertificate(&s, &m.certificate) && - s.ReadUint32(&m.maxEarlyData) && - readUint8LengthPrefixed(&s, &alpn) && - readUint16LengthPrefixed(&s, &m.appData) && - s.Empty() - m.alpn = string(alpn) - return ret -} - -func (c *Conn) encryptTicket(state []byte) ([]byte, error) { - if len(c.ticketKeys) == 0 { - return nil, errors.New("tls: internal error: session ticket keys unavailable") - } - - encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size) - keyName := encrypted[:ticketKeyNameLen] - iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - - if _, err := io.ReadFull(c.config.rand(), iv); err != nil { - return nil, err - } - key := c.ticketKeys[0] - copy(keyName, key.keyName[:]) - block, err := aes.NewCipher(key.aesKey[:]) - if err != nil { - return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) - } - cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state) - - mac := hmac.New(sha256.New, key.hmacKey[:]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - mac.Sum(macBytes[:0]) - - return encrypted, nil -} - -func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) { - if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size { - return nil, false - } - - keyName := encrypted[:ticketKeyNameLen] - iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size] - - keyIndex := -1 - for i, candidateKey := range c.ticketKeys { - if bytes.Equal(keyName, candidateKey.keyName[:]) { - keyIndex = i - break - } - } - if keyIndex == -1 { - return nil, false - } - key := &c.ticketKeys[keyIndex] - - mac := hmac.New(sha256.New, key.hmacKey[:]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - expected := mac.Sum(nil) - - if subtle.ConstantTimeCompare(macBytes, expected) != 1 { - return nil, false - } - - block, err := aes.NewCipher(key.aesKey[:]) - if err != nil { - return nil, false - } - plaintext = make([]byte, len(ciphertext)) - cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext) - - return plaintext, keyIndex > 0 -} - -func (c *Conn) getSessionTicketMsg(appData []byte) (*newSessionTicketMsgTLS13, error) { - m := new(newSessionTicketMsgTLS13) - - var certsFromClient [][]byte - for _, cert := range c.peerCertificates { - certsFromClient = append(certsFromClient, cert.Raw) - } - state := sessionStateTLS13{ - cipherSuite: c.cipherSuite, - createdAt: uint64(c.config.time().Unix()), - resumptionSecret: c.resumptionSecret, - certificate: Certificate{ - Certificate: certsFromClient, - OCSPStaple: c.ocspResponse, - SignedCertificateTimestamps: c.scts, - }, - appData: appData, - alpn: c.clientProtocol, - } - if c.extraConfig != nil { - state.maxEarlyData = c.extraConfig.MaxEarlyData - } - var err error - m.label, err = c.encryptTicket(state.marshal()) - if err != nil { - return nil, err - } - m.lifetime = uint32(maxSessionTicketLifetime / time.Second) - if c.extraConfig != nil { - m.maxEarlyData = c.extraConfig.MaxEarlyData - } - return m, nil -} - -// GetSessionTicket generates a new session ticket. -// It should only be called after the handshake completes. -// It can only be used for servers, and only if the alternative record layer is set. -// The ticket may be nil if config.SessionTicketsDisabled is set, -// or if the client isn't able to receive session tickets. -func (c *Conn) GetSessionTicket(appData []byte) ([]byte, error) { - if c.isClient || !c.handshakeComplete() || c.extraConfig == nil || c.extraConfig.AlternativeRecordLayer == nil { - return nil, errors.New("GetSessionTicket is only valid for servers after completion of the handshake, and if an alternative record layer is set.") - } - if c.config.SessionTicketsDisabled { - return nil, nil - } - - m, err := c.getSessionTicketMsg(appData) - if err != nil { - return nil, err - } - return m.marshal(), nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/tls.go b/vendor/github.com/marten-seemann/qtls-go1-16/tls.go deleted file mode 100644 index 10cbae03b..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/tls.go +++ /dev/null @@ -1,393 +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 qtls partially implements TLS 1.2, as specified in RFC 5246, -// and TLS 1.3, as specified in RFC 8446. -package qtls - -// BUG(agl): The crypto/tls package only implements some countermeasures -// against Lucky13 attacks on CBC-mode encryption, and only on SHA1 -// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and -// https://www.imperialviolet.org/2013/02/04/luckythirteen.html. - -import ( - "bytes" - "context" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" - "fmt" - "net" - "os" - "strings" - "time" -) - -// Server returns a new TLS server side connection -// using conn as the underlying transport. -// The configuration config must be non-nil and must include -// at least one certificate or else set GetCertificate. -func Server(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - c := &Conn{ - conn: conn, - config: fromConfig(config), - extraConfig: extraConfig, - } - c.handshakeFn = c.serverHandshake - return c -} - -// Client returns a new TLS client side connection -// using conn as the underlying transport. -// The config cannot be nil: users must set either ServerName or -// InsecureSkipVerify in the config. -func Client(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - c := &Conn{ - conn: conn, - config: fromConfig(config), - extraConfig: extraConfig, - isClient: true, - } - c.handshakeFn = c.clientHandshake - return c -} - -// A listener implements a network listener (net.Listener) for TLS connections. -type listener struct { - net.Listener - config *Config - extraConfig *ExtraConfig -} - -// Accept waits for and returns the next incoming TLS connection. -// The returned connection is of type *Conn. -func (l *listener) Accept() (net.Conn, error) { - c, err := l.Listener.Accept() - if err != nil { - return nil, err - } - return Server(c, l.config, l.extraConfig), nil -} - -// NewListener creates a Listener which accepts connections from an inner -// Listener and wraps each connection with Server. -// The configuration config must be non-nil and must include -// at least one certificate or else set GetCertificate. -func NewListener(inner net.Listener, config *Config, extraConfig *ExtraConfig) net.Listener { - l := new(listener) - l.Listener = inner - l.config = config - l.extraConfig = extraConfig - return l -} - -// Listen creates a TLS listener accepting connections on the -// given network address using net.Listen. -// The configuration config must be non-nil and must include -// at least one certificate or else set GetCertificate. -func Listen(network, laddr string, config *Config, extraConfig *ExtraConfig) (net.Listener, error) { - if config == nil || len(config.Certificates) == 0 && - config.GetCertificate == nil && config.GetConfigForClient == nil { - return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config") - } - l, err := net.Listen(network, laddr) - if err != nil { - return nil, err - } - return NewListener(l, config, extraConfig), nil -} - -type timeoutError struct{} - -func (timeoutError) Error() string { return "tls: DialWithDialer timed out" } -func (timeoutError) Timeout() bool { return true } -func (timeoutError) Temporary() bool { return true } - -// DialWithDialer connects to the given network address using dialer.Dial and -// then initiates a TLS handshake, returning the resulting TLS connection. Any -// timeout or deadline given in the dialer apply to connection and TLS -// handshake as a whole. -// -// DialWithDialer interprets a nil configuration as equivalent to the zero -// configuration; see the documentation of Config for the defaults. -func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) { - return dial(context.Background(), dialer, network, addr, config, extraConfig) -} - -func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) { - // We want the Timeout and Deadline values from dialer to cover the - // whole process: TCP connection and TLS handshake. This means that we - // also need to start our own timers now. - timeout := netDialer.Timeout - - if !netDialer.Deadline.IsZero() { - deadlineTimeout := time.Until(netDialer.Deadline) - if timeout == 0 || deadlineTimeout < timeout { - timeout = deadlineTimeout - } - } - - // hsErrCh is non-nil if we might not wait for Handshake to complete. - var hsErrCh chan error - if timeout != 0 || ctx.Done() != nil { - hsErrCh = make(chan error, 2) - } - if timeout != 0 { - timer := time.AfterFunc(timeout, func() { - hsErrCh <- timeoutError{} - }) - defer timer.Stop() - } - - rawConn, err := netDialer.DialContext(ctx, network, addr) - if err != nil { - return nil, err - } - - colonPos := strings.LastIndex(addr, ":") - if colonPos == -1 { - colonPos = len(addr) - } - hostname := addr[:colonPos] - - if config == nil { - config = defaultConfig() - } - // If no ServerName is set, infer the ServerName - // from the hostname we're connecting to. - if config.ServerName == "" { - // Make a copy to avoid polluting argument or default. - c := config.Clone() - c.ServerName = hostname - config = c - } - - conn := Client(rawConn, config, extraConfig) - - if hsErrCh == nil { - err = conn.Handshake() - } else { - go func() { - hsErrCh <- conn.Handshake() - }() - - select { - case <-ctx.Done(): - err = ctx.Err() - case err = <-hsErrCh: - if err != nil { - // If the error was due to the context - // closing, prefer the context's error, rather - // than some random network teardown error. - if e := ctx.Err(); e != nil { - err = e - } - } - } - } - - if err != nil { - rawConn.Close() - return nil, err - } - - return conn, nil -} - -// Dial connects to the given network address using net.Dial -// and then initiates a TLS handshake, returning the resulting -// TLS connection. -// Dial interprets a nil configuration as equivalent to -// the zero configuration; see the documentation of Config -// for the defaults. -func Dial(network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) { - return DialWithDialer(new(net.Dialer), network, addr, config, extraConfig) -} - -// Dialer dials TLS connections given a configuration and a Dialer for the -// underlying connection. -type Dialer struct { - // NetDialer is the optional dialer to use for the TLS connections' - // underlying TCP connections. - // A nil NetDialer is equivalent to the net.Dialer zero value. - NetDialer *net.Dialer - - // Config is the TLS configuration to use for new connections. - // A nil configuration is equivalent to the zero - // configuration; see the documentation of Config for the - // defaults. - Config *Config - - ExtraConfig *ExtraConfig -} - -// Dial connects to the given network address and initiates a TLS -// handshake, returning the resulting TLS connection. -// -// The returned Conn, if any, will always be of type *Conn. -func (d *Dialer) Dial(network, addr string) (net.Conn, error) { - return d.DialContext(context.Background(), network, addr) -} - -func (d *Dialer) netDialer() *net.Dialer { - if d.NetDialer != nil { - return d.NetDialer - } - return new(net.Dialer) -} - -// DialContext connects to the given network address and initiates a TLS -// handshake, returning the resulting TLS connection. -// -// The provided Context must be non-nil. If the context expires before -// the connection is complete, an error is returned. Once successfully -// connected, any expiration of the context will not affect the -// connection. -// -// The returned Conn, if any, will always be of type *Conn. -func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { - c, err := dial(ctx, d.netDialer(), network, addr, d.Config, d.ExtraConfig) - if err != nil { - // Don't return c (a typed nil) in an interface. - return nil, err - } - return c, nil -} - -// LoadX509KeyPair reads and parses a public/private key pair from a pair -// of files. The files must contain PEM encoded data. The certificate file -// may contain intermediate certificates following the leaf certificate to -// form a certificate chain. On successful return, Certificate.Leaf will -// be nil because the parsed form of the certificate is not retained. -func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) { - certPEMBlock, err := os.ReadFile(certFile) - if err != nil { - return Certificate{}, err - } - keyPEMBlock, err := os.ReadFile(keyFile) - if err != nil { - return Certificate{}, err - } - return X509KeyPair(certPEMBlock, keyPEMBlock) -} - -// X509KeyPair parses a public/private key pair from a pair of -// PEM encoded data. On successful return, Certificate.Leaf will be nil because -// the parsed form of the certificate is not retained. -func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { - fail := func(err error) (Certificate, error) { return Certificate{}, err } - - var cert Certificate - var skippedBlockTypes []string - for { - var certDERBlock *pem.Block - certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) - if certDERBlock == nil { - break - } - if certDERBlock.Type == "CERTIFICATE" { - cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) - } else { - skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) - } - } - - if len(cert.Certificate) == 0 { - if len(skippedBlockTypes) == 0 { - return fail(errors.New("tls: failed to find any PEM data in certificate input")) - } - if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { - return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched")) - } - return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) - } - - skippedBlockTypes = skippedBlockTypes[:0] - var keyDERBlock *pem.Block - for { - keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) - if keyDERBlock == nil { - if len(skippedBlockTypes) == 0 { - return fail(errors.New("tls: failed to find any PEM data in key input")) - } - if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { - return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key")) - } - return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) - } - if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { - break - } - skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) - } - - // We don't need to parse the public key for TLS, but we so do anyway - // to check that it looks sane and matches the private key. - x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - return fail(err) - } - - cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) - if err != nil { - return fail(err) - } - - switch pub := x509Cert.PublicKey.(type) { - case *rsa.PublicKey: - priv, ok := cert.PrivateKey.(*rsa.PrivateKey) - if !ok { - return fail(errors.New("tls: private key type does not match public key type")) - } - if pub.N.Cmp(priv.N) != 0 { - return fail(errors.New("tls: private key does not match public key")) - } - case *ecdsa.PublicKey: - priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) - if !ok { - return fail(errors.New("tls: private key type does not match public key type")) - } - if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { - return fail(errors.New("tls: private key does not match public key")) - } - case ed25519.PublicKey: - priv, ok := cert.PrivateKey.(ed25519.PrivateKey) - if !ok { - return fail(errors.New("tls: private key type does not match public key type")) - } - if !bytes.Equal(priv.Public().(ed25519.PublicKey), pub) { - return fail(errors.New("tls: private key does not match public key")) - } - default: - return fail(errors.New("tls: unknown public key algorithm")) - } - - return cert, nil -} - -// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates -// PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys. -// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. -func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { - if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { - return key, nil - } - if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { - switch key := key.(type) { - case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey: - return key, nil - default: - return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping") - } - } - if key, err := x509.ParseECPrivateKey(der); err == nil { - return key, nil - } - - return nil, errors.New("tls: failed to parse private key") -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/unsafe.go b/vendor/github.com/marten-seemann/qtls-go1-16/unsafe.go deleted file mode 100644 index 55fa01b3d..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-16/unsafe.go +++ /dev/null @@ -1,96 +0,0 @@ -package qtls - -import ( - "crypto/tls" - "reflect" - "unsafe" -) - -func init() { - if !structsEqual(&tls.ConnectionState{}, &connectionState{}) { - panic("qtls.ConnectionState doesn't match") - } - if !structsEqual(&tls.ClientSessionState{}, &clientSessionState{}) { - panic("qtls.ClientSessionState doesn't match") - } - if !structsEqual(&tls.CertificateRequestInfo{}, &certificateRequestInfo{}) { - panic("qtls.CertificateRequestInfo doesn't match") - } - if !structsEqual(&tls.Config{}, &config{}) { - panic("qtls.Config doesn't match") - } - if !structsEqual(&tls.ClientHelloInfo{}, &clientHelloInfo{}) { - panic("qtls.ClientHelloInfo doesn't match") - } -} - -func toConnectionState(c connectionState) ConnectionState { - return *(*ConnectionState)(unsafe.Pointer(&c)) -} - -func toClientSessionState(s *clientSessionState) *ClientSessionState { - return (*ClientSessionState)(unsafe.Pointer(s)) -} - -func fromClientSessionState(s *ClientSessionState) *clientSessionState { - return (*clientSessionState)(unsafe.Pointer(s)) -} - -func toCertificateRequestInfo(i *certificateRequestInfo) *CertificateRequestInfo { - return (*CertificateRequestInfo)(unsafe.Pointer(i)) -} - -func toConfig(c *config) *Config { - return (*Config)(unsafe.Pointer(c)) -} - -func fromConfig(c *Config) *config { - return (*config)(unsafe.Pointer(c)) -} - -func toClientHelloInfo(chi *clientHelloInfo) *ClientHelloInfo { - return (*ClientHelloInfo)(unsafe.Pointer(chi)) -} - -func structsEqual(a, b interface{}) bool { - return compare(reflect.ValueOf(a), reflect.ValueOf(b)) -} - -func compare(a, b reflect.Value) bool { - sa := a.Elem() - sb := b.Elem() - if sa.NumField() != sb.NumField() { - return false - } - for i := 0; i < sa.NumField(); i++ { - fa := sa.Type().Field(i) - fb := sb.Type().Field(i) - if !reflect.DeepEqual(fa.Index, fb.Index) || fa.Name != fb.Name || fa.Anonymous != fb.Anonymous || fa.Offset != fb.Offset || !reflect.DeepEqual(fa.Type, fb.Type) { - if fa.Type.Kind() != fb.Type.Kind() { - return false - } - if fa.Type.Kind() == reflect.Slice { - if !compareStruct(fa.Type.Elem(), fb.Type.Elem()) { - return false - } - continue - } - return false - } - } - return true -} - -func compareStruct(a, b reflect.Type) bool { - if a.NumField() != b.NumField() { - return false - } - for i := 0; i < a.NumField(); i++ { - fa := a.Field(i) - fb := b.Field(i) - if !reflect.DeepEqual(fa.Index, fb.Index) || fa.Name != fb.Name || fa.Anonymous != fb.Anonymous || fa.Offset != fb.Offset || !reflect.DeepEqual(fa.Type, fb.Type) { - return false - } - } - return true -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/README.md b/vendor/github.com/marten-seemann/qtls-go1-17/README.md deleted file mode 100644 index 3e9022127..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# qtls - -[![Go Reference](https://pkg.go.dev/badge/github.com/marten-seemann/qtls-go1-17.svg)](https://pkg.go.dev/github.com/marten-seemann/qtls-go1-17) -[![.github/workflows/go-test.yml](https://github.com/marten-seemann/qtls-go1-17/actions/workflows/go-test.yml/badge.svg)](https://github.com/marten-seemann/qtls-go1-17/actions/workflows/go-test.yml) - -This repository contains a modified version of the standard library's TLS implementation, modified for the QUIC protocol. It is used by [quic-go](https://github.com/lucas-clemente/quic-go). diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/alert.go b/vendor/github.com/marten-seemann/qtls-go1-17/alert.go deleted file mode 100644 index 3feac79be..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/alert.go +++ /dev/null @@ -1,102 +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 qtls - -import "strconv" - -type alert uint8 - -// Alert is a TLS alert -type Alert = alert - -const ( - // alert level - alertLevelWarning = 1 - alertLevelError = 2 -) - -const ( - alertCloseNotify alert = 0 - alertUnexpectedMessage alert = 10 - alertBadRecordMAC alert = 20 - alertDecryptionFailed alert = 21 - alertRecordOverflow alert = 22 - alertDecompressionFailure alert = 30 - alertHandshakeFailure alert = 40 - alertBadCertificate alert = 42 - alertUnsupportedCertificate alert = 43 - alertCertificateRevoked alert = 44 - alertCertificateExpired alert = 45 - alertCertificateUnknown alert = 46 - alertIllegalParameter alert = 47 - alertUnknownCA alert = 48 - alertAccessDenied alert = 49 - alertDecodeError alert = 50 - alertDecryptError alert = 51 - alertExportRestriction alert = 60 - alertProtocolVersion alert = 70 - alertInsufficientSecurity alert = 71 - alertInternalError alert = 80 - alertInappropriateFallback alert = 86 - alertUserCanceled alert = 90 - alertNoRenegotiation alert = 100 - alertMissingExtension alert = 109 - alertUnsupportedExtension alert = 110 - alertCertificateUnobtainable alert = 111 - alertUnrecognizedName alert = 112 - alertBadCertificateStatusResponse alert = 113 - alertBadCertificateHashValue alert = 114 - alertUnknownPSKIdentity alert = 115 - alertCertificateRequired alert = 116 - alertNoApplicationProtocol alert = 120 -) - -var alertText = map[alert]string{ - alertCloseNotify: "close notify", - alertUnexpectedMessage: "unexpected message", - alertBadRecordMAC: "bad record MAC", - alertDecryptionFailed: "decryption failed", - alertRecordOverflow: "record overflow", - alertDecompressionFailure: "decompression failure", - alertHandshakeFailure: "handshake failure", - alertBadCertificate: "bad certificate", - alertUnsupportedCertificate: "unsupported certificate", - alertCertificateRevoked: "revoked certificate", - alertCertificateExpired: "expired certificate", - alertCertificateUnknown: "unknown certificate", - alertIllegalParameter: "illegal parameter", - alertUnknownCA: "unknown certificate authority", - alertAccessDenied: "access denied", - alertDecodeError: "error decoding message", - alertDecryptError: "error decrypting message", - alertExportRestriction: "export restriction", - alertProtocolVersion: "protocol version not supported", - alertInsufficientSecurity: "insufficient security level", - alertInternalError: "internal error", - alertInappropriateFallback: "inappropriate fallback", - alertUserCanceled: "user canceled", - alertNoRenegotiation: "no renegotiation", - alertMissingExtension: "missing extension", - alertUnsupportedExtension: "unsupported extension", - alertCertificateUnobtainable: "certificate unobtainable", - alertUnrecognizedName: "unrecognized name", - alertBadCertificateStatusResponse: "bad certificate status response", - alertBadCertificateHashValue: "bad certificate hash value", - alertUnknownPSKIdentity: "unknown PSK identity", - alertCertificateRequired: "certificate required", - alertNoApplicationProtocol: "no application protocol", -} - -func (e alert) String() string { - s, ok := alertText[e] - if ok { - return "tls: " + s - } - return "tls: alert(" + strconv.Itoa(int(e)) + ")" -} - -func (e alert) Error() string { - return e.String() -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/auth.go b/vendor/github.com/marten-seemann/qtls-go1-17/auth.go deleted file mode 100644 index 1ef675fd3..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/auth.go +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" - "crypto/rsa" - "errors" - "fmt" - "hash" - "io" -) - -// verifyHandshakeSignature verifies a signature against pre-hashed -// (if required) handshake contents. -func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error { - switch sigType { - case signatureECDSA: - pubKey, ok := pubkey.(*ecdsa.PublicKey) - if !ok { - return fmt.Errorf("expected an ECDSA public key, got %T", pubkey) - } - if !ecdsa.VerifyASN1(pubKey, signed, sig) { - return errors.New("ECDSA verification failure") - } - case signatureEd25519: - pubKey, ok := pubkey.(ed25519.PublicKey) - if !ok { - return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey) - } - if !ed25519.Verify(pubKey, signed, sig) { - return errors.New("Ed25519 verification failure") - } - case signaturePKCS1v15: - pubKey, ok := pubkey.(*rsa.PublicKey) - if !ok { - return fmt.Errorf("expected an RSA public key, got %T", pubkey) - } - if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil { - return err - } - case signatureRSAPSS: - pubKey, ok := pubkey.(*rsa.PublicKey) - if !ok { - return fmt.Errorf("expected an RSA public key, got %T", pubkey) - } - signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash} - if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil { - return err - } - default: - return errors.New("internal error: unknown signature type") - } - return nil -} - -const ( - serverSignatureContext = "TLS 1.3, server CertificateVerify\x00" - clientSignatureContext = "TLS 1.3, client CertificateVerify\x00" -) - -var signaturePadding = []byte{ - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, -} - -// signedMessage returns the pre-hashed (if necessary) message to be signed by -// certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3. -func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) []byte { - if sigHash == directSigning { - b := &bytes.Buffer{} - b.Write(signaturePadding) - io.WriteString(b, context) - b.Write(transcript.Sum(nil)) - return b.Bytes() - } - h := sigHash.New() - h.Write(signaturePadding) - io.WriteString(h, context) - h.Write(transcript.Sum(nil)) - return h.Sum(nil) -} - -// typeAndHashFromSignatureScheme returns the corresponding signature type and -// crypto.Hash for a given TLS SignatureScheme. -func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) { - switch signatureAlgorithm { - case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512: - sigType = signaturePKCS1v15 - case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512: - sigType = signatureRSAPSS - case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512: - sigType = signatureECDSA - case Ed25519: - sigType = signatureEd25519 - default: - return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) - } - switch signatureAlgorithm { - case PKCS1WithSHA1, ECDSAWithSHA1: - hash = crypto.SHA1 - case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256: - hash = crypto.SHA256 - case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384: - hash = crypto.SHA384 - case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512: - hash = crypto.SHA512 - case Ed25519: - hash = directSigning - default: - return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm) - } - return sigType, hash, nil -} - -// legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for -// a given public key used with TLS 1.0 and 1.1, before the introduction of -// signature algorithm negotiation. -func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) { - switch pub.(type) { - case *rsa.PublicKey: - return signaturePKCS1v15, crypto.MD5SHA1, nil - case *ecdsa.PublicKey: - return signatureECDSA, crypto.SHA1, nil - case ed25519.PublicKey: - // RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1, - // but it requires holding on to a handshake transcript to do a - // full signature, and not even OpenSSL bothers with the - // complexity, so we can't even test it properly. - return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2") - default: - return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub) - } -} - -var rsaSignatureSchemes = []struct { - scheme SignatureScheme - minModulusBytes int - maxVersion uint16 -}{ - // RSA-PSS is used with PSSSaltLengthEqualsHash, and requires - // emLen >= hLen + sLen + 2 - {PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13}, - {PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13}, - {PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13}, - // PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires - // emLen >= len(prefix) + hLen + 11 - // TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS. - {PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12}, - {PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12}, - {PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12}, - {PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12}, -} - -// signatureSchemesForCertificate returns the list of supported SignatureSchemes -// for a given certificate, based on the public key and the protocol version, -// and optionally filtered by its explicit SupportedSignatureAlgorithms. -// -// This function must be kept in sync with supportedSignatureAlgorithms. -func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme { - priv, ok := cert.PrivateKey.(crypto.Signer) - if !ok { - return nil - } - - var sigAlgs []SignatureScheme - switch pub := priv.Public().(type) { - case *ecdsa.PublicKey: - if version != VersionTLS13 { - // In TLS 1.2 and earlier, ECDSA algorithms are not - // constrained to a single curve. - sigAlgs = []SignatureScheme{ - ECDSAWithP256AndSHA256, - ECDSAWithP384AndSHA384, - ECDSAWithP521AndSHA512, - ECDSAWithSHA1, - } - break - } - switch pub.Curve { - case elliptic.P256(): - sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256} - case elliptic.P384(): - sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384} - case elliptic.P521(): - sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512} - default: - return nil - } - case *rsa.PublicKey: - size := pub.Size() - sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes)) - for _, candidate := range rsaSignatureSchemes { - if size >= candidate.minModulusBytes && version <= candidate.maxVersion { - sigAlgs = append(sigAlgs, candidate.scheme) - } - } - case ed25519.PublicKey: - sigAlgs = []SignatureScheme{Ed25519} - default: - return nil - } - - if cert.SupportedSignatureAlgorithms != nil { - var filteredSigAlgs []SignatureScheme - for _, sigAlg := range sigAlgs { - if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) { - filteredSigAlgs = append(filteredSigAlgs, sigAlg) - } - } - return filteredSigAlgs - } - return sigAlgs -} - -// selectSignatureScheme picks a SignatureScheme from the peer's preference list -// that works with the selected certificate. It's only called for protocol -// versions that support signature algorithms, so TLS 1.2 and 1.3. -func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) { - supportedAlgs := signatureSchemesForCertificate(vers, c) - if len(supportedAlgs) == 0 { - return 0, unsupportedCertificateError(c) - } - if len(peerAlgs) == 0 && vers == VersionTLS12 { - // For TLS 1.2, if the client didn't send signature_algorithms then we - // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1. - peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1} - } - // Pick signature scheme in the peer's preference order, as our - // preference order is not configurable. - for _, preferredAlg := range peerAlgs { - if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) { - return preferredAlg, nil - } - } - return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms") -} - -// unsupportedCertificateError returns a helpful error for certificates with -// an unsupported private key. -func unsupportedCertificateError(cert *Certificate) error { - switch cert.PrivateKey.(type) { - case rsa.PrivateKey, ecdsa.PrivateKey: - return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T", - cert.PrivateKey, cert.PrivateKey) - case *ed25519.PrivateKey: - return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey") - } - - signer, ok := cert.PrivateKey.(crypto.Signer) - if !ok { - return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer", - cert.PrivateKey) - } - - switch pub := signer.Public().(type) { - case *ecdsa.PublicKey: - switch pub.Curve { - case elliptic.P256(): - case elliptic.P384(): - case elliptic.P521(): - default: - return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name) - } - case *rsa.PublicKey: - return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms") - case ed25519.PublicKey: - default: - return fmt.Errorf("tls: unsupported certificate key (%T)", pub) - } - - if cert.SupportedSignatureAlgorithms != nil { - return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms") - } - - return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey) -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/cipher_suites.go b/vendor/github.com/marten-seemann/qtls-go1-17/cipher_suites.go deleted file mode 100644 index 53a3956aa..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/cipher_suites.go +++ /dev/null @@ -1,691 +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 qtls - -import ( - "crypto" - "crypto/aes" - "crypto/cipher" - "crypto/des" - "crypto/hmac" - "crypto/rc4" - "crypto/sha1" - "crypto/sha256" - "fmt" - "hash" - - "golang.org/x/crypto/chacha20poly1305" -) - -// CipherSuite is a TLS cipher suite. Note that most functions in this package -// accept and expose cipher suite IDs instead of this type. -type CipherSuite struct { - ID uint16 - Name string - - // Supported versions is the list of TLS protocol versions that can - // negotiate this cipher suite. - SupportedVersions []uint16 - - // Insecure is true if the cipher suite has known security issues - // due to its primitives, design, or implementation. - Insecure bool -} - -var ( - supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12} - supportedOnlyTLS12 = []uint16{VersionTLS12} - supportedOnlyTLS13 = []uint16{VersionTLS13} -) - -// CipherSuites returns a list of cipher suites currently implemented by this -// package, excluding those with security issues, which are returned by -// InsecureCipherSuites. -// -// The list is sorted by ID. Note that the default cipher suites selected by -// this package might depend on logic that can't be captured by a static list, -// and might not match those returned by this function. -func CipherSuites() []*CipherSuite { - return []*CipherSuite{ - {TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, - {TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, - {TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, - {TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, - - {TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false}, - {TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false}, - {TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false}, - - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false}, - {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false}, - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false}, - } -} - -// InsecureCipherSuites returns a list of cipher suites currently implemented by -// this package and which have security issues. -// -// Most applications should not use the cipher suites in this list, and should -// only use those returned by CipherSuites. -func InsecureCipherSuites() []*CipherSuite { - // This list includes RC4, CBC_SHA256, and 3DES cipher suites. See - // cipherSuitesPreferenceOrder for details. - return []*CipherSuite{ - {TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true}, - {TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true}, - } -} - -// CipherSuiteName returns the standard name for the passed cipher suite ID -// (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation -// of the ID value if the cipher suite is not implemented by this package. -func CipherSuiteName(id uint16) string { - for _, c := range CipherSuites() { - if c.ID == id { - return c.Name - } - } - for _, c := range InsecureCipherSuites() { - if c.ID == id { - return c.Name - } - } - return fmt.Sprintf("0x%04X", id) -} - -const ( - // suiteECDHE indicates that the cipher suite involves elliptic curve - // Diffie-Hellman. This means that it should only be selected when the - // client indicates that it supports ECC with a curve and point format - // that we're happy with. - suiteECDHE = 1 << iota - // suiteECSign indicates that the cipher suite involves an ECDSA or - // EdDSA signature and therefore may only be selected when the server's - // certificate is ECDSA or EdDSA. If this is not set then the cipher suite - // is RSA based. - suiteECSign - // suiteTLS12 indicates that the cipher suite should only be advertised - // and accepted when using TLS 1.2. - suiteTLS12 - // suiteSHA384 indicates that the cipher suite uses SHA384 as the - // handshake hash. - suiteSHA384 -) - -// A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange -// mechanism, as well as the cipher+MAC pair or the AEAD. -type cipherSuite struct { - id uint16 - // the lengths, in bytes, of the key material needed for each component. - keyLen int - macLen int - ivLen int - ka func(version uint16) keyAgreement - // flags is a bitmask of the suite* values, above. - flags int - cipher func(key, iv []byte, isRead bool) interface{} - mac func(key []byte) hash.Hash - aead func(key, fixedNonce []byte) aead -} - -var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order doesn't matter. - {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, - {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305}, - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM}, - {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil}, - {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, - {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil}, -} - -// selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which -// is also in supportedIDs and passes the ok filter. -func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite { - for _, id := range ids { - candidate := cipherSuiteByID(id) - if candidate == nil || !ok(candidate) { - continue - } - - for _, suppID := range supportedIDs { - if id == suppID { - return candidate - } - } - } - return nil -} - -// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash -// algorithm to be used with HKDF. See RFC 8446, Appendix B.4. -type cipherSuiteTLS13 struct { - id uint16 - keyLen int - aead func(key, fixedNonce []byte) aead - hash crypto.Hash -} - -type CipherSuiteTLS13 struct { - ID uint16 - KeyLen int - Hash crypto.Hash - AEAD func(key, fixedNonce []byte) cipher.AEAD -} - -func (c *CipherSuiteTLS13) IVLen() int { - return aeadNonceLength -} - -var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map. - {TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256}, - {TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256}, - {TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384}, -} - -// cipherSuitesPreferenceOrder is the order in which we'll select (on the -// server) or advertise (on the client) TLS 1.0–1.2 cipher suites. -// -// Cipher suites are filtered but not reordered based on the application and -// peer's preferences, meaning we'll never select a suite lower in this list if -// any higher one is available. This makes it more defensible to keep weaker -// cipher suites enabled, especially on the server side where we get the last -// word, since there are no known downgrade attacks on cipher suites selection. -// -// The list is sorted by applying the following priority rules, stopping at the -// first (most important) applicable one: -// -// - Anything else comes before RC4 -// -// RC4 has practically exploitable biases. See https://www.rc4nomore.com. -// -// - Anything else comes before CBC_SHA256 -// -// SHA-256 variants of the CBC ciphersuites don't implement any Lucky13 -// countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and -// https://www.imperialviolet.org/2013/02/04/luckythirteen.html. -// -// - Anything else comes before 3DES -// -// 3DES has 64-bit blocks, which makes it fundamentally susceptible to -// birthday attacks. See https://sweet32.info. -// -// - ECDHE comes before anything else -// -// Once we got the broken stuff out of the way, the most important -// property a cipher suite can have is forward secrecy. We don't -// implement FFDHE, so that means ECDHE. -// -// - AEADs come before CBC ciphers -// -// Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites -// are fundamentally fragile, and suffered from an endless sequence of -// padding oracle attacks. See https://eprint.iacr.org/2015/1129, -// https://www.imperialviolet.org/2014/12/08/poodleagain.html, and -// https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/. -// -// - AES comes before ChaCha20 -// -// When AES hardware is available, AES-128-GCM and AES-256-GCM are faster -// than ChaCha20Poly1305. -// -// When AES hardware is not available, AES-128-GCM is one or more of: much -// slower, way more complex, and less safe (because not constant time) -// than ChaCha20Poly1305. -// -// We use this list if we think both peers have AES hardware, and -// cipherSuitesPreferenceOrderNoAES otherwise. -// -// - AES-128 comes before AES-256 -// -// The only potential advantages of AES-256 are better multi-target -// margins, and hypothetical post-quantum properties. Neither apply to -// TLS, and AES-256 is slower due to its four extra rounds (which don't -// contribute to the advantages above). -// -// - ECDSA comes before RSA -// -// The relative order of ECDSA and RSA cipher suites doesn't matter, -// as they depend on the certificate. Pick one to get a stable order. -// -var cipherSuitesPreferenceOrder = []uint16{ - // AEADs w/ ECDHE - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - - // CBC w/ ECDHE - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - - // AEADs w/o ECDHE - TLS_RSA_WITH_AES_128_GCM_SHA256, - TLS_RSA_WITH_AES_256_GCM_SHA384, - - // CBC w/o ECDHE - TLS_RSA_WITH_AES_128_CBC_SHA, - TLS_RSA_WITH_AES_256_CBC_SHA, - - // 3DES - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_RSA_WITH_3DES_EDE_CBC_SHA, - - // CBC_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - TLS_RSA_WITH_AES_128_CBC_SHA256, - - // RC4 - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, - TLS_RSA_WITH_RC4_128_SHA, -} - -var cipherSuitesPreferenceOrderNoAES = []uint16{ - // ChaCha20Poly1305 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - - // AES-GCM w/ ECDHE - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - - // The rest of cipherSuitesPreferenceOrder. - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - TLS_RSA_WITH_AES_128_GCM_SHA256, - TLS_RSA_WITH_AES_256_GCM_SHA384, - TLS_RSA_WITH_AES_128_CBC_SHA, - TLS_RSA_WITH_AES_256_CBC_SHA, - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_RSA_WITH_3DES_EDE_CBC_SHA, - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - TLS_RSA_WITH_AES_128_CBC_SHA256, - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, - TLS_RSA_WITH_RC4_128_SHA, -} - -// disabledCipherSuites are not used unless explicitly listed in -// Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder. -var disabledCipherSuites = []uint16{ - // CBC_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - TLS_RSA_WITH_AES_128_CBC_SHA256, - - // RC4 - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, - TLS_RSA_WITH_RC4_128_SHA, -} - -var ( - defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites) - defaultCipherSuites = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen] -) - -// defaultCipherSuitesTLS13 is also the preference order, since there are no -// disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as -// cipherSuitesPreferenceOrder applies. -var defaultCipherSuitesTLS13 = []uint16{ - TLS_AES_128_GCM_SHA256, - TLS_AES_256_GCM_SHA384, - TLS_CHACHA20_POLY1305_SHA256, -} - -var defaultCipherSuitesTLS13NoAES = []uint16{ - TLS_CHACHA20_POLY1305_SHA256, - TLS_AES_128_GCM_SHA256, - TLS_AES_256_GCM_SHA384, -} - -var aesgcmCiphers = map[uint16]bool{ - // TLS 1.2 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true, - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true, - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true, - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true, - // TLS 1.3 - TLS_AES_128_GCM_SHA256: true, - TLS_AES_256_GCM_SHA384: true, -} - -var nonAESGCMAEADCiphers = map[uint16]bool{ - // TLS 1.2 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true, - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true, - // TLS 1.3 - TLS_CHACHA20_POLY1305_SHA256: true, -} - -// aesgcmPreferred returns whether the first known cipher in the preference list -// is an AES-GCM cipher, implying the peer has hardware support for it. -func aesgcmPreferred(ciphers []uint16) bool { - for _, cID := range ciphers { - if c := cipherSuiteByID(cID); c != nil { - return aesgcmCiphers[cID] - } - if c := cipherSuiteTLS13ByID(cID); c != nil { - return aesgcmCiphers[cID] - } - } - return false -} - -func cipherRC4(key, iv []byte, isRead bool) interface{} { - cipher, _ := rc4.NewCipher(key) - return cipher -} - -func cipher3DES(key, iv []byte, isRead bool) interface{} { - block, _ := des.NewTripleDESCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -func cipherAES(key, iv []byte, isRead bool) interface{} { - block, _ := aes.NewCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -// macSHA1 returns a SHA-1 based constant time MAC. -func macSHA1(key []byte) hash.Hash { - return hmac.New(newConstantTimeHash(sha1.New), key) -} - -// macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and -// is currently only used in disabled-by-default cipher suites. -func macSHA256(key []byte) hash.Hash { - return hmac.New(sha256.New, key) -} - -type aead interface { - cipher.AEAD - - // explicitNonceLen returns the number of bytes of explicit nonce - // included in each record. This is eight for older AEADs and - // zero for modern ones. - explicitNonceLen() int -} - -const ( - aeadNonceLength = 12 - noncePrefixLength = 4 -) - -// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to -// each call. -type prefixNonceAEAD struct { - // nonce contains the fixed part of the nonce in the first four bytes. - nonce [aeadNonceLength]byte - aead cipher.AEAD -} - -func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength } -func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() } -func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() } - -func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { - copy(f.nonce[4:], nonce) - return f.aead.Seal(out, f.nonce[:], plaintext, additionalData) -} - -func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { - copy(f.nonce[4:], nonce) - return f.aead.Open(out, f.nonce[:], ciphertext, additionalData) -} - -// xoredNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce -// before each call. -type xorNonceAEAD struct { - nonceMask [aeadNonceLength]byte - aead cipher.AEAD -} - -func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number -func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() } -func (f *xorNonceAEAD) explicitNonceLen() int { return 0 } - -func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData) - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - - return result -} - -func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) { - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData) - for i, b := range nonce { - f.nonceMask[4+i] ^= b - } - - return result, err -} - -func aeadAESGCM(key, noncePrefix []byte) aead { - if len(noncePrefix) != noncePrefixLength { - panic("tls: internal error: wrong nonce length") - } - aes, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - aead, err := cipher.NewGCM(aes) - if err != nil { - panic(err) - } - - ret := &prefixNonceAEAD{aead: aead} - copy(ret.nonce[:], noncePrefix) - return ret -} - -// AEADAESGCMTLS13 creates a new AES-GCM AEAD for TLS 1.3 -func AEADAESGCMTLS13(key, fixedNonce []byte) cipher.AEAD { - return aeadAESGCMTLS13(key, fixedNonce) -} - -func aeadAESGCMTLS13(key, nonceMask []byte) aead { - if len(nonceMask) != aeadNonceLength { - panic("tls: internal error: wrong nonce length") - } - aes, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - aead, err := cipher.NewGCM(aes) - if err != nil { - panic(err) - } - - ret := &xorNonceAEAD{aead: aead} - copy(ret.nonceMask[:], nonceMask) - return ret -} - -func aeadChaCha20Poly1305(key, nonceMask []byte) aead { - if len(nonceMask) != aeadNonceLength { - panic("tls: internal error: wrong nonce length") - } - aead, err := chacha20poly1305.New(key) - if err != nil { - panic(err) - } - - ret := &xorNonceAEAD{aead: aead} - copy(ret.nonceMask[:], nonceMask) - return ret -} - -type constantTimeHash interface { - hash.Hash - ConstantTimeSum(b []byte) []byte -} - -// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces -// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC. -type cthWrapper struct { - h constantTimeHash -} - -func (c *cthWrapper) Size() int { return c.h.Size() } -func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() } -func (c *cthWrapper) Reset() { c.h.Reset() } -func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) } -func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) } - -func newConstantTimeHash(h func() hash.Hash) func() hash.Hash { - return func() hash.Hash { - return &cthWrapper{h().(constantTimeHash)} - } -} - -// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3. -func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte { - h.Reset() - h.Write(seq) - h.Write(header) - h.Write(data) - res := h.Sum(out) - if extra != nil { - h.Write(extra) - } - return res -} - -func rsaKA(version uint16) keyAgreement { - return rsaKeyAgreement{} -} - -func ecdheECDSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - isRSA: false, - version: version, - } -} - -func ecdheRSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - isRSA: true, - version: version, - } -} - -// mutualCipherSuite returns a cipherSuite given a list of supported -// ciphersuites and the id requested by the peer. -func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { - for _, id := range have { - if id == want { - return cipherSuiteByID(id) - } - } - return nil -} - -func cipherSuiteByID(id uint16) *cipherSuite { - for _, cipherSuite := range cipherSuites { - if cipherSuite.id == id { - return cipherSuite - } - } - return nil -} - -func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 { - for _, id := range have { - if id == want { - return cipherSuiteTLS13ByID(id) - } - } - return nil -} - -func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 { - for _, cipherSuite := range cipherSuitesTLS13 { - if cipherSuite.id == id { - return cipherSuite - } - } - return nil -} - -// A list of cipher suite IDs that are, or have been, implemented by this -// package. -// -// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml -const ( - // TLS 1.0 - 1.2 cipher suites. - TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a - TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f - TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c - TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c - TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a - TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030 - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9 - - // TLS 1.3 cipher suites. - TLS_AES_128_GCM_SHA256 uint16 = 0x1301 - TLS_AES_256_GCM_SHA384 uint16 = 0x1302 - TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303 - - // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator - // that the client is doing version fallback. See RFC 7507. - TLS_FALLBACK_SCSV uint16 = 0x5600 - - // Legacy names for the corresponding cipher suites with the correct _SHA256 - // suffix, retained for backward compatibility. - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 -) diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/common.go b/vendor/github.com/marten-seemann/qtls-go1-17/common.go deleted file mode 100644 index 8a9b68048..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/common.go +++ /dev/null @@ -1,1485 +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 qtls - -import ( - "bytes" - "container/list" - "context" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/elliptic" - "crypto/rand" - "crypto/rsa" - "crypto/sha512" - "crypto/tls" - "crypto/x509" - "errors" - "fmt" - "io" - "net" - "strings" - "sync" - "time" -) - -const ( - VersionTLS10 = 0x0301 - VersionTLS11 = 0x0302 - VersionTLS12 = 0x0303 - VersionTLS13 = 0x0304 - - // Deprecated: SSLv3 is cryptographically broken, and is no longer - // supported by this package. See golang.org/issue/32716. - VersionSSL30 = 0x0300 -) - -const ( - maxPlaintext = 16384 // maximum plaintext payload length - maxCiphertext = 16384 + 2048 // maximum ciphertext payload length - maxCiphertextTLS13 = 16384 + 256 // maximum ciphertext length in TLS 1.3 - recordHeaderLen = 5 // record header length - maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) - maxUselessRecords = 16 // maximum number of consecutive non-advancing records -) - -// TLS record types. -type recordType uint8 - -const ( - recordTypeChangeCipherSpec recordType = 20 - recordTypeAlert recordType = 21 - recordTypeHandshake recordType = 22 - recordTypeApplicationData recordType = 23 -) - -// TLS handshake message types. -const ( - typeHelloRequest uint8 = 0 - typeClientHello uint8 = 1 - typeServerHello uint8 = 2 - typeNewSessionTicket uint8 = 4 - typeEndOfEarlyData uint8 = 5 - typeEncryptedExtensions uint8 = 8 - typeCertificate uint8 = 11 - typeServerKeyExchange uint8 = 12 - typeCertificateRequest uint8 = 13 - typeServerHelloDone uint8 = 14 - typeCertificateVerify uint8 = 15 - typeClientKeyExchange uint8 = 16 - typeFinished uint8 = 20 - typeCertificateStatus uint8 = 22 - typeKeyUpdate uint8 = 24 - typeNextProtocol uint8 = 67 // Not IANA assigned - typeMessageHash uint8 = 254 // synthetic message -) - -// TLS compression types. -const ( - compressionNone uint8 = 0 -) - -type Extension struct { - Type uint16 - Data []byte -} - -// TLS extension numbers -const ( - extensionServerName uint16 = 0 - extensionStatusRequest uint16 = 5 - extensionSupportedCurves uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7 - extensionSupportedPoints uint16 = 11 - extensionSignatureAlgorithms uint16 = 13 - extensionALPN uint16 = 16 - extensionSCT uint16 = 18 - extensionSessionTicket uint16 = 35 - extensionPreSharedKey uint16 = 41 - extensionEarlyData uint16 = 42 - extensionSupportedVersions uint16 = 43 - extensionCookie uint16 = 44 - extensionPSKModes uint16 = 45 - extensionCertificateAuthorities uint16 = 47 - extensionSignatureAlgorithmsCert uint16 = 50 - extensionKeyShare uint16 = 51 - extensionRenegotiationInfo uint16 = 0xff01 -) - -// TLS signaling cipher suite values -const ( - scsvRenegotiation uint16 = 0x00ff -) - -type EncryptionLevel uint8 - -const ( - EncryptionHandshake EncryptionLevel = iota - Encryption0RTT - EncryptionApplication -) - -// CurveID is a tls.CurveID -type CurveID = tls.CurveID - -const ( - CurveP256 CurveID = 23 - CurveP384 CurveID = 24 - CurveP521 CurveID = 25 - X25519 CurveID = 29 -) - -// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8. -type keyShare struct { - group CurveID - data []byte -} - -// TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9. -const ( - pskModePlain uint8 = 0 - pskModeDHE uint8 = 1 -) - -// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved -// session. See RFC 8446, Section 4.2.11. -type pskIdentity struct { - label []byte - obfuscatedTicketAge uint32 -} - -// TLS Elliptic Curve Point Formats -// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 -const ( - pointFormatUncompressed uint8 = 0 -) - -// TLS CertificateStatusType (RFC 3546) -const ( - statusTypeOCSP uint8 = 1 -) - -// Certificate types (for certificateRequestMsg) -const ( - certTypeRSASign = 1 - certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3. -) - -// Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with -// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do. -const ( - signaturePKCS1v15 uint8 = iota + 225 - signatureRSAPSS - signatureECDSA - signatureEd25519 -) - -// directSigning is a standard Hash value that signals that no pre-hashing -// should be performed, and that the input should be signed directly. It is the -// hash function associated with the Ed25519 signature scheme. -var directSigning crypto.Hash = 0 - -// supportedSignatureAlgorithms contains the signature and hash algorithms that -// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+ -// CertificateRequest. The two fields are merged to match with TLS 1.3. -// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc. -var supportedSignatureAlgorithms = []SignatureScheme{ - PSSWithSHA256, - ECDSAWithP256AndSHA256, - Ed25519, - PSSWithSHA384, - PSSWithSHA512, - PKCS1WithSHA256, - PKCS1WithSHA384, - PKCS1WithSHA512, - ECDSAWithP384AndSHA384, - ECDSAWithP521AndSHA512, - PKCS1WithSHA1, - ECDSAWithSHA1, -} - -// helloRetryRequestRandom is set as the Random value of a ServerHello -// to signal that the message is actually a HelloRetryRequest. -var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3. - 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, - 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91, - 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, - 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C, -} - -const ( - // downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server - // random as a downgrade protection if the server would be capable of - // negotiating a higher version. See RFC 8446, Section 4.1.3. - downgradeCanaryTLS12 = "DOWNGRD\x01" - downgradeCanaryTLS11 = "DOWNGRD\x00" -) - -// testingOnlyForceDowngradeCanary is set in tests to force the server side to -// include downgrade canaries even if it's using its highers supported version. -var testingOnlyForceDowngradeCanary bool - -type ConnectionState = tls.ConnectionState - -// ConnectionState records basic TLS details about the connection. -type connectionState struct { - // Version is the TLS version used by the connection (e.g. VersionTLS12). - Version uint16 - - // HandshakeComplete is true if the handshake has concluded. - HandshakeComplete bool - - // DidResume is true if this connection was successfully resumed from a - // previous session with a session ticket or similar mechanism. - DidResume bool - - // CipherSuite is the cipher suite negotiated for the connection (e.g. - // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256). - CipherSuite uint16 - - // NegotiatedProtocol is the application protocol negotiated with ALPN. - NegotiatedProtocol string - - // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation. - // - // Deprecated: this value is always true. - NegotiatedProtocolIsMutual bool - - // ServerName is the value of the Server Name Indication extension sent by - // the client. It's available both on the server and on the client side. - ServerName string - - // PeerCertificates are the parsed certificates sent by the peer, in the - // order in which they were sent. The first element is the leaf certificate - // that the connection is verified against. - // - // On the client side, it can't be empty. On the server side, it can be - // empty if Config.ClientAuth is not RequireAnyClientCert or - // RequireAndVerifyClientCert. - PeerCertificates []*x509.Certificate - - // VerifiedChains is a list of one or more chains where the first element is - // PeerCertificates[0] and the last element is from Config.RootCAs (on the - // client side) or Config.ClientCAs (on the server side). - // - // On the client side, it's set if Config.InsecureSkipVerify is false. On - // the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven - // (and the peer provided a certificate) or RequireAndVerifyClientCert. - VerifiedChains [][]*x509.Certificate - - // SignedCertificateTimestamps is a list of SCTs provided by the peer - // through the TLS handshake for the leaf certificate, if any. - SignedCertificateTimestamps [][]byte - - // OCSPResponse is a stapled Online Certificate Status Protocol (OCSP) - // response provided by the peer for the leaf certificate, if any. - OCSPResponse []byte - - // TLSUnique contains the "tls-unique" channel binding value (see RFC 5929, - // Section 3). This value will be nil for TLS 1.3 connections and for all - // resumed connections. - // - // Deprecated: there are conditions in which this value might not be unique - // to a connection. See the Security Considerations sections of RFC 5705 and - // RFC 7627, and https://mitls.org/pages/attacks/3SHAKE#channelbindings. - TLSUnique []byte - - // ekm is a closure exposed via ExportKeyingMaterial. - ekm func(label string, context []byte, length int) ([]byte, error) -} - -type ConnectionStateWith0RTT struct { - ConnectionState - - Used0RTT bool // true if 0-RTT was both offered and accepted -} - -// ClientAuthType is tls.ClientAuthType -type ClientAuthType = tls.ClientAuthType - -const ( - NoClientCert = tls.NoClientCert - RequestClientCert = tls.RequestClientCert - RequireAnyClientCert = tls.RequireAnyClientCert - VerifyClientCertIfGiven = tls.VerifyClientCertIfGiven - RequireAndVerifyClientCert = tls.RequireAndVerifyClientCert -) - -// requiresClientCert reports whether the ClientAuthType requires a client -// certificate to be provided. -func requiresClientCert(c ClientAuthType) bool { - switch c { - case RequireAnyClientCert, RequireAndVerifyClientCert: - return true - default: - return false - } -} - -// ClientSessionState contains the state needed by clients to resume TLS -// sessions. -type ClientSessionState = tls.ClientSessionState - -type clientSessionState struct { - sessionTicket []uint8 // Encrypted ticket used for session resumption with server - vers uint16 // TLS version negotiated for the session - cipherSuite uint16 // Ciphersuite negotiated for the session - masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret - serverCertificates []*x509.Certificate // Certificate chain presented by the server - verifiedChains [][]*x509.Certificate // Certificate chains we built for verification - receivedAt time.Time // When the session ticket was received from the server - ocspResponse []byte // Stapled OCSP response presented by the server - scts [][]byte // SCTs presented by the server - - // TLS 1.3 fields. - nonce []byte // Ticket nonce sent by the server, to derive PSK - useBy time.Time // Expiration of the ticket lifetime as set by the server - ageAdd uint32 // Random obfuscation factor for sending the ticket age -} - -// ClientSessionCache is a cache of ClientSessionState objects that can be used -// by a client to resume a TLS session with a given server. ClientSessionCache -// implementations should expect to be called concurrently from different -// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not -// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which -// are supported via this interface. -//go:generate sh -c "mockgen -package qtls -destination mock_client_session_cache_test.go github.com/marten-seemann/qtls-go1-17 ClientSessionCache" -type ClientSessionCache = tls.ClientSessionCache - -// SignatureScheme is a tls.SignatureScheme -type SignatureScheme = tls.SignatureScheme - -const ( - // RSASSA-PKCS1-v1_5 algorithms. - PKCS1WithSHA256 SignatureScheme = 0x0401 - PKCS1WithSHA384 SignatureScheme = 0x0501 - PKCS1WithSHA512 SignatureScheme = 0x0601 - - // RSASSA-PSS algorithms with public key OID rsaEncryption. - PSSWithSHA256 SignatureScheme = 0x0804 - PSSWithSHA384 SignatureScheme = 0x0805 - PSSWithSHA512 SignatureScheme = 0x0806 - - // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3. - ECDSAWithP256AndSHA256 SignatureScheme = 0x0403 - ECDSAWithP384AndSHA384 SignatureScheme = 0x0503 - ECDSAWithP521AndSHA512 SignatureScheme = 0x0603 - - // EdDSA algorithms. - Ed25519 SignatureScheme = 0x0807 - - // Legacy signature and hash algorithms for TLS 1.2. - PKCS1WithSHA1 SignatureScheme = 0x0201 - ECDSAWithSHA1 SignatureScheme = 0x0203 -) - -// ClientHelloInfo contains information from a ClientHello message in order to -// guide application logic in the GetCertificate and GetConfigForClient callbacks. -type ClientHelloInfo = tls.ClientHelloInfo - -type clientHelloInfo struct { - // CipherSuites lists the CipherSuites supported by the client (e.g. - // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256). - CipherSuites []uint16 - - // ServerName indicates the name of the server requested by the client - // in order to support virtual hosting. ServerName is only set if the - // client is using SNI (see RFC 4366, Section 3.1). - ServerName string - - // SupportedCurves lists the elliptic curves supported by the client. - // SupportedCurves is set only if the Supported Elliptic Curves - // Extension is being used (see RFC 4492, Section 5.1.1). - SupportedCurves []CurveID - - // SupportedPoints lists the point formats supported by the client. - // SupportedPoints is set only if the Supported Point Formats Extension - // is being used (see RFC 4492, Section 5.1.2). - SupportedPoints []uint8 - - // SignatureSchemes lists the signature and hash schemes that the client - // is willing to verify. SignatureSchemes is set only if the Signature - // Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1). - SignatureSchemes []SignatureScheme - - // SupportedProtos lists the application protocols supported by the client. - // SupportedProtos is set only if the Application-Layer Protocol - // Negotiation Extension is being used (see RFC 7301, Section 3.1). - // - // Servers can select a protocol by setting Config.NextProtos in a - // GetConfigForClient return value. - SupportedProtos []string - - // SupportedVersions lists the TLS versions supported by the client. - // For TLS versions less than 1.3, this is extrapolated from the max - // version advertised by the client, so values other than the greatest - // might be rejected if used. - SupportedVersions []uint16 - - // Conn is the underlying net.Conn for the connection. Do not read - // from, or write to, this connection; that will cause the TLS - // connection to fail. - Conn net.Conn - - // config is embedded by the GetCertificate or GetConfigForClient caller, - // for use with SupportsCertificate. - config *Config - - // ctx is the context of the handshake that is in progress. - ctx context.Context -} - -// Context returns the context of the handshake that is in progress. -// This context is a child of the context passed to HandshakeContext, -// if any, and is canceled when the handshake concludes. -func (c *clientHelloInfo) Context() context.Context { - return c.ctx -} - -// CertificateRequestInfo contains information from a server's -// CertificateRequest message, which is used to demand a certificate and proof -// of control from a client. -type CertificateRequestInfo = tls.CertificateRequestInfo - -type certificateRequestInfo struct { - // AcceptableCAs contains zero or more, DER-encoded, X.501 - // Distinguished Names. These are the names of root or intermediate CAs - // that the server wishes the returned certificate to be signed by. An - // empty slice indicates that the server has no preference. - AcceptableCAs [][]byte - - // SignatureSchemes lists the signature schemes that the server is - // willing to verify. - SignatureSchemes []SignatureScheme - - // Version is the TLS version that was negotiated for this connection. - Version uint16 - - // ctx is the context of the handshake that is in progress. - ctx context.Context -} - -// Context returns the context of the handshake that is in progress. -// This context is a child of the context passed to HandshakeContext, -// if any, and is canceled when the handshake concludes. -func (c *certificateRequestInfo) Context() context.Context { - return c.ctx -} - -// RenegotiationSupport enumerates the different levels of support for TLS -// renegotiation. TLS renegotiation is the act of performing subsequent -// handshakes on a connection after the first. This significantly complicates -// the state machine and has been the source of numerous, subtle security -// issues. Initiating a renegotiation is not supported, but support for -// accepting renegotiation requests may be enabled. -// -// Even when enabled, the server may not change its identity between handshakes -// (i.e. the leaf certificate must be the same). Additionally, concurrent -// handshake and application data flow is not permitted so renegotiation can -// only be used with protocols that synchronise with the renegotiation, such as -// HTTPS. -// -// Renegotiation is not defined in TLS 1.3. -type RenegotiationSupport = tls.RenegotiationSupport - -const ( - // RenegotiateNever disables renegotiation. - RenegotiateNever = tls.RenegotiateNever - - // RenegotiateOnceAsClient allows a remote server to request - // renegotiation once per connection. - RenegotiateOnceAsClient = tls.RenegotiateOnceAsClient - - // RenegotiateFreelyAsClient allows a remote server to repeatedly - // request renegotiation. - RenegotiateFreelyAsClient = tls.RenegotiateFreelyAsClient -) - -// A Config structure is used to configure a TLS client or server. -// After one has been passed to a TLS function it must not be -// modified. A Config may be reused; the tls package will also not -// modify it. -type Config = tls.Config - -type config struct { - // Rand provides the source of entropy for nonces and RSA blinding. - // If Rand is nil, TLS uses the cryptographic random reader in package - // crypto/rand. - // The Reader must be safe for use by multiple goroutines. - Rand io.Reader - - // Time returns the current time as the number of seconds since the epoch. - // If Time is nil, TLS uses time.Now. - Time func() time.Time - - // Certificates contains one or more certificate chains to present to the - // other side of the connection. The first certificate compatible with the - // peer's requirements is selected automatically. - // - // Server configurations must set one of Certificates, GetCertificate or - // GetConfigForClient. Clients doing client-authentication may set either - // Certificates or GetClientCertificate. - // - // Note: if there are multiple Certificates, and they don't have the - // optional field Leaf set, certificate selection will incur a significant - // per-handshake performance cost. - Certificates []Certificate - - // NameToCertificate maps from a certificate name to an element of - // Certificates. Note that a certificate name can be of the form - // '*.example.com' and so doesn't have to be a domain name as such. - // - // Deprecated: NameToCertificate only allows associating a single - // certificate with a given name. Leave this field nil to let the library - // select the first compatible chain from Certificates. - NameToCertificate map[string]*Certificate - - // GetCertificate returns a Certificate based on the given - // ClientHelloInfo. It will only be called if the client supplies SNI - // information or if Certificates is empty. - // - // If GetCertificate is nil or returns nil, then the certificate is - // retrieved from NameToCertificate. If NameToCertificate is nil, the - // best element of Certificates will be used. - GetCertificate func(*ClientHelloInfo) (*Certificate, error) - - // GetClientCertificate, if not nil, is called when a server requests a - // certificate from a client. If set, the contents of Certificates will - // be ignored. - // - // If GetClientCertificate returns an error, the handshake will be - // aborted and that error will be returned. Otherwise - // GetClientCertificate must return a non-nil Certificate. If - // Certificate.Certificate is empty then no certificate will be sent to - // the server. If this is unacceptable to the server then it may abort - // the handshake. - // - // GetClientCertificate may be called multiple times for the same - // connection if renegotiation occurs or if TLS 1.3 is in use. - GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error) - - // GetConfigForClient, if not nil, is called after a ClientHello is - // received from a client. It may return a non-nil Config in order to - // change the Config that will be used to handle this connection. If - // the returned Config is nil, the original Config will be used. The - // Config returned by this callback may not be subsequently modified. - // - // If GetConfigForClient is nil, the Config passed to Server() will be - // used for all connections. - // - // If SessionTicketKey was explicitly set on the returned Config, or if - // SetSessionTicketKeys was called on the returned Config, those keys will - // be used. Otherwise, the original Config keys will be used (and possibly - // rotated if they are automatically managed). - GetConfigForClient func(*ClientHelloInfo) (*Config, error) - - // VerifyPeerCertificate, if not nil, is called after normal - // certificate verification by either a TLS client or server. It - // receives the raw ASN.1 certificates provided by the peer and also - // any verified chains that normal processing found. If it returns a - // non-nil error, the handshake is aborted and that error results. - // - // If normal verification fails then the handshake will abort before - // considering this callback. If normal verification is disabled by - // setting InsecureSkipVerify, or (for a server) when ClientAuth is - // RequestClientCert or RequireAnyClientCert, then this callback will - // be considered but the verifiedChains argument will always be nil. - VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error - - // VerifyConnection, if not nil, is called after normal certificate - // verification and after VerifyPeerCertificate by either a TLS client - // or server. If it returns a non-nil error, the handshake is aborted - // and that error results. - // - // If normal verification fails then the handshake will abort before - // considering this callback. This callback will run for all connections - // regardless of InsecureSkipVerify or ClientAuth settings. - VerifyConnection func(ConnectionState) error - - // RootCAs defines the set of root certificate authorities - // that clients use when verifying server certificates. - // If RootCAs is nil, TLS uses the host's root CA set. - RootCAs *x509.CertPool - - // NextProtos is a list of supported application level protocols, in - // order of preference. If both peers support ALPN, the selected - // protocol will be one from this list, and the connection will fail - // if there is no mutually supported protocol. If NextProtos is empty - // or the peer doesn't support ALPN, the connection will succeed and - // ConnectionState.NegotiatedProtocol will be empty. - NextProtos []string - - // ServerName is used to verify the hostname on the returned - // certificates unless InsecureSkipVerify is given. It is also included - // in the client's handshake to support virtual hosting unless it is - // an IP address. - ServerName string - - // ClientAuth determines the server's policy for - // TLS Client Authentication. The default is NoClientCert. - ClientAuth ClientAuthType - - // ClientCAs defines the set of root certificate authorities - // that servers use if required to verify a client certificate - // by the policy in ClientAuth. - ClientCAs *x509.CertPool - - // InsecureSkipVerify controls whether a client verifies the server's - // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls - // accepts any certificate presented by the server and any host name in that - // certificate. In this mode, TLS is susceptible to machine-in-the-middle - // attacks unless custom verification is used. This should be used only for - // testing or in combination with VerifyConnection or VerifyPeerCertificate. - InsecureSkipVerify bool - - // CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of - // the list is ignored. Note that TLS 1.3 ciphersuites are not configurable. - // - // If CipherSuites is nil, a safe default list is used. The default cipher - // suites might change over time. - CipherSuites []uint16 - - // PreferServerCipherSuites is a legacy field and has no effect. - // - // It used to control whether the server would follow the client's or the - // server's preference. Servers now select the best mutually supported - // cipher suite based on logic that takes into account inferred client - // hardware, server hardware, and security. - // - // Deprected: PreferServerCipherSuites is ignored. - PreferServerCipherSuites bool - - // SessionTicketsDisabled may be set to true to disable session ticket and - // PSK (resumption) support. Note that on clients, session ticket support is - // also disabled if ClientSessionCache is nil. - SessionTicketsDisabled bool - - // SessionTicketKey is used by TLS servers to provide session resumption. - // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled - // with random data before the first server handshake. - // - // Deprecated: if this field is left at zero, session ticket keys will be - // automatically rotated every day and dropped after seven days. For - // customizing the rotation schedule or synchronizing servers that are - // terminating connections for the same host, use SetSessionTicketKeys. - SessionTicketKey [32]byte - - // ClientSessionCache is a cache of ClientSessionState entries for TLS - // session resumption. It is only used by clients. - ClientSessionCache ClientSessionCache - - // MinVersion contains the minimum TLS version that is acceptable. - // If zero, TLS 1.0 is currently taken as the minimum. - MinVersion uint16 - - // MaxVersion contains the maximum TLS version that is acceptable. - // If zero, the maximum version supported by this package is used, - // which is currently TLS 1.3. - MaxVersion uint16 - - // CurvePreferences contains the elliptic curves that will be used in - // an ECDHE handshake, in preference order. If empty, the default will - // be used. The client will use the first preference as the type for - // its key share in TLS 1.3. This may change in the future. - CurvePreferences []CurveID - - // DynamicRecordSizingDisabled disables adaptive sizing of TLS records. - // When true, the largest possible TLS record size is always used. When - // false, the size of TLS records may be adjusted in an attempt to - // improve latency. - DynamicRecordSizingDisabled bool - - // Renegotiation controls what types of renegotiation are supported. - // The default, none, is correct for the vast majority of applications. - Renegotiation RenegotiationSupport - - // KeyLogWriter optionally specifies a destination for TLS master secrets - // in NSS key log format that can be used to allow external programs - // such as Wireshark to decrypt TLS connections. - // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. - // Use of KeyLogWriter compromises security and should only be - // used for debugging. - KeyLogWriter io.Writer - - // mutex protects sessionTicketKeys and autoSessionTicketKeys. - mutex sync.RWMutex - // sessionTicketKeys contains zero or more ticket keys. If set, it means the - // the keys were set with SessionTicketKey or SetSessionTicketKeys. The - // first key is used for new tickets and any subsequent keys can be used to - // decrypt old tickets. The slice contents are not protected by the mutex - // and are immutable. - sessionTicketKeys []ticketKey - // autoSessionTicketKeys is like sessionTicketKeys but is owned by the - // auto-rotation logic. See Config.ticketKeys. - autoSessionTicketKeys []ticketKey -} - -// A RecordLayer handles encrypting and decrypting of TLS messages. -type RecordLayer interface { - SetReadKey(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte) - SetWriteKey(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte) - ReadHandshakeMessage() ([]byte, error) - WriteRecord([]byte) (int, error) - SendAlert(uint8) -} - -type ExtraConfig struct { - // GetExtensions, if not nil, is called before a message that allows - // sending of extensions is sent. - // Currently only implemented for the ClientHello message (for the client) - // and for the EncryptedExtensions message (for the server). - // Only valid for TLS 1.3. - GetExtensions func(handshakeMessageType uint8) []Extension - - // ReceivedExtensions, if not nil, is called when a message that allows the - // inclusion of extensions is received. - // It is called with an empty slice of extensions, if the message didn't - // contain any extensions. - // Currently only implemented for the ClientHello message (sent by the - // client) and for the EncryptedExtensions message (sent by the server). - // Only valid for TLS 1.3. - ReceivedExtensions func(handshakeMessageType uint8, exts []Extension) - - // AlternativeRecordLayer is used by QUIC - AlternativeRecordLayer RecordLayer - - // Enforce the selection of a supported application protocol. - // Only works for TLS 1.3. - // If enabled, client and server have to agree on an application protocol. - // Otherwise, connection establishment fails. - EnforceNextProtoSelection bool - - // If MaxEarlyData is greater than 0, the client will be allowed to send early - // data when resuming a session. - // Requires the AlternativeRecordLayer to be set. - // - // It has no meaning on the client. - MaxEarlyData uint32 - - // The Accept0RTT callback is called when the client offers 0-RTT. - // The server then has to decide if it wants to accept or reject 0-RTT. - // It is only used for servers. - Accept0RTT func(appData []byte) bool - - // 0RTTRejected is called when the server rejectes 0-RTT. - // It is only used for clients. - Rejected0RTT func() - - // If set, the client will export the 0-RTT key when resuming a session that - // allows sending of early data. - // Requires the AlternativeRecordLayer to be set. - // - // It has no meaning to the server. - Enable0RTT bool - - // Is called when the client saves a session ticket to the session ticket. - // This gives the application the opportunity to save some data along with the ticket, - // which can be restored when the session ticket is used. - GetAppDataForSessionState func() []byte - - // Is called when the client uses a session ticket. - // Restores the application data that was saved earlier on GetAppDataForSessionTicket. - SetAppDataFromSessionState func([]byte) -} - -// Clone clones. -func (c *ExtraConfig) Clone() *ExtraConfig { - return &ExtraConfig{ - GetExtensions: c.GetExtensions, - ReceivedExtensions: c.ReceivedExtensions, - AlternativeRecordLayer: c.AlternativeRecordLayer, - EnforceNextProtoSelection: c.EnforceNextProtoSelection, - MaxEarlyData: c.MaxEarlyData, - Enable0RTT: c.Enable0RTT, - Accept0RTT: c.Accept0RTT, - Rejected0RTT: c.Rejected0RTT, - GetAppDataForSessionState: c.GetAppDataForSessionState, - SetAppDataFromSessionState: c.SetAppDataFromSessionState, - } -} - -func (c *ExtraConfig) usesAlternativeRecordLayer() bool { - return c != nil && c.AlternativeRecordLayer != nil -} - -const ( - // ticketKeyNameLen is the number of bytes of identifier that is prepended to - // an encrypted session ticket in order to identify the key used to encrypt it. - ticketKeyNameLen = 16 - - // ticketKeyLifetime is how long a ticket key remains valid and can be used to - // resume a client connection. - ticketKeyLifetime = 7 * 24 * time.Hour // 7 days - - // ticketKeyRotation is how often the server should rotate the session ticket key - // that is used for new tickets. - ticketKeyRotation = 24 * time.Hour -) - -// ticketKey is the internal representation of a session ticket key. -type ticketKey struct { - // keyName is an opaque byte string that serves to identify the session - // ticket key. It's exposed as plaintext in every session ticket. - keyName [ticketKeyNameLen]byte - aesKey [16]byte - hmacKey [16]byte - // created is the time at which this ticket key was created. See Config.ticketKeys. - created time.Time -} - -// ticketKeyFromBytes converts from the external representation of a session -// ticket key to a ticketKey. Externally, session ticket keys are 32 random -// bytes and this function expands that into sufficient name and key material. -func (c *config) ticketKeyFromBytes(b [32]byte) (key ticketKey) { - hashed := sha512.Sum512(b[:]) - copy(key.keyName[:], hashed[:ticketKeyNameLen]) - copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16]) - copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32]) - key.created = c.time() - return key -} - -// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session -// ticket, and the lifetime we set for tickets we send. -const maxSessionTicketLifetime = 7 * 24 * time.Hour - -// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is -// being used concurrently by a TLS client or server. -func (c *config) Clone() *config { - if c == nil { - return nil - } - c.mutex.RLock() - defer c.mutex.RUnlock() - return &config{ - Rand: c.Rand, - Time: c.Time, - Certificates: c.Certificates, - NameToCertificate: c.NameToCertificate, - GetCertificate: c.GetCertificate, - GetClientCertificate: c.GetClientCertificate, - GetConfigForClient: c.GetConfigForClient, - VerifyPeerCertificate: c.VerifyPeerCertificate, - VerifyConnection: c.VerifyConnection, - RootCAs: c.RootCAs, - NextProtos: c.NextProtos, - ServerName: c.ServerName, - ClientAuth: c.ClientAuth, - ClientCAs: c.ClientCAs, - InsecureSkipVerify: c.InsecureSkipVerify, - CipherSuites: c.CipherSuites, - PreferServerCipherSuites: c.PreferServerCipherSuites, - SessionTicketsDisabled: c.SessionTicketsDisabled, - SessionTicketKey: c.SessionTicketKey, - ClientSessionCache: c.ClientSessionCache, - MinVersion: c.MinVersion, - MaxVersion: c.MaxVersion, - CurvePreferences: c.CurvePreferences, - DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled, - Renegotiation: c.Renegotiation, - KeyLogWriter: c.KeyLogWriter, - sessionTicketKeys: c.sessionTicketKeys, - autoSessionTicketKeys: c.autoSessionTicketKeys, - } -} - -// deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was -// randomized for backwards compatibility but is not in use. -var deprecatedSessionTicketKey = []byte("DEPRECATED") - -// initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is -// randomized if empty, and that sessionTicketKeys is populated from it otherwise. -func (c *config) initLegacySessionTicketKeyRLocked() { - // Don't write if SessionTicketKey is already defined as our deprecated string, - // or if it is defined by the user but sessionTicketKeys is already set. - if c.SessionTicketKey != [32]byte{} && - (bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) { - return - } - - // We need to write some data, so get an exclusive lock and re-check any conditions. - c.mutex.RUnlock() - defer c.mutex.RLock() - c.mutex.Lock() - defer c.mutex.Unlock() - if c.SessionTicketKey == [32]byte{} { - if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { - panic(fmt.Sprintf("tls: unable to generate random session ticket key: %v", err)) - } - // Write the deprecated prefix at the beginning so we know we created - // it. This key with the DEPRECATED prefix isn't used as an actual - // session ticket key, and is only randomized in case the application - // reuses it for some reason. - copy(c.SessionTicketKey[:], deprecatedSessionTicketKey) - } else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 { - c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)} - } - -} - -// ticketKeys returns the ticketKeys for this connection. -// If configForClient has explicitly set keys, those will -// be returned. Otherwise, the keys on c will be used and -// may be rotated if auto-managed. -// During rotation, any expired session ticket keys are deleted from -// c.sessionTicketKeys. If the session ticket key that is currently -// encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys) -// is not fresh, then a new session ticket key will be -// created and prepended to c.sessionTicketKeys. -func (c *config) ticketKeys(configForClient *config) []ticketKey { - // If the ConfigForClient callback returned a Config with explicitly set - // keys, use those, otherwise just use the original Config. - if configForClient != nil { - configForClient.mutex.RLock() - if configForClient.SessionTicketsDisabled { - return nil - } - configForClient.initLegacySessionTicketKeyRLocked() - if len(configForClient.sessionTicketKeys) != 0 { - ret := configForClient.sessionTicketKeys - configForClient.mutex.RUnlock() - return ret - } - configForClient.mutex.RUnlock() - } - - c.mutex.RLock() - defer c.mutex.RUnlock() - if c.SessionTicketsDisabled { - return nil - } - c.initLegacySessionTicketKeyRLocked() - if len(c.sessionTicketKeys) != 0 { - return c.sessionTicketKeys - } - // Fast path for the common case where the key is fresh enough. - if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation { - return c.autoSessionTicketKeys - } - - // autoSessionTicketKeys are managed by auto-rotation. - c.mutex.RUnlock() - defer c.mutex.RLock() - c.mutex.Lock() - defer c.mutex.Unlock() - // Re-check the condition in case it changed since obtaining the new lock. - if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation { - var newKey [32]byte - if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil { - panic(fmt.Sprintf("unable to generate random session ticket key: %v", err)) - } - valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1) - valid = append(valid, c.ticketKeyFromBytes(newKey)) - for _, k := range c.autoSessionTicketKeys { - // While rotating the current key, also remove any expired ones. - if c.time().Sub(k.created) < ticketKeyLifetime { - valid = append(valid, k) - } - } - c.autoSessionTicketKeys = valid - } - return c.autoSessionTicketKeys -} - -// SetSessionTicketKeys updates the session ticket keys for a server. -// -// The first key will be used when creating new tickets, while all keys can be -// used for decrypting tickets. It is safe to call this function while the -// server is running in order to rotate the session ticket keys. The function -// will panic if keys is empty. -// -// Calling this function will turn off automatic session ticket key rotation. -// -// If multiple servers are terminating connections for the same host they should -// all have the same session ticket keys. If the session ticket keys leaks, -// previously recorded and future TLS connections using those keys might be -// compromised. -func (c *config) SetSessionTicketKeys(keys [][32]byte) { - if len(keys) == 0 { - panic("tls: keys must have at least one key") - } - - newKeys := make([]ticketKey, len(keys)) - for i, bytes := range keys { - newKeys[i] = c.ticketKeyFromBytes(bytes) - } - - c.mutex.Lock() - c.sessionTicketKeys = newKeys - c.mutex.Unlock() -} - -func (c *config) rand() io.Reader { - r := c.Rand - if r == nil { - return rand.Reader - } - return r -} - -func (c *config) time() time.Time { - t := c.Time - if t == nil { - t = time.Now - } - return t() -} - -func (c *config) cipherSuites() []uint16 { - if c.CipherSuites != nil { - return c.CipherSuites - } - return defaultCipherSuites -} - -var supportedVersions = []uint16{ - VersionTLS13, - VersionTLS12, - VersionTLS11, - VersionTLS10, -} - -func (c *config) supportedVersions() []uint16 { - versions := make([]uint16, 0, len(supportedVersions)) - for _, v := range supportedVersions { - if c != nil && c.MinVersion != 0 && v < c.MinVersion { - continue - } - if c != nil && c.MaxVersion != 0 && v > c.MaxVersion { - continue - } - versions = append(versions, v) - } - return versions -} - -func (c *config) maxSupportedVersion() uint16 { - supportedVersions := c.supportedVersions() - if len(supportedVersions) == 0 { - return 0 - } - return supportedVersions[0] -} - -// supportedVersionsFromMax returns a list of supported versions derived from a -// legacy maximum version value. Note that only versions supported by this -// library are returned. Any newer peer will use supportedVersions anyway. -func supportedVersionsFromMax(maxVersion uint16) []uint16 { - versions := make([]uint16, 0, len(supportedVersions)) - for _, v := range supportedVersions { - if v > maxVersion { - continue - } - versions = append(versions, v) - } - return versions -} - -var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521} - -func (c *config) curvePreferences() []CurveID { - if c == nil || len(c.CurvePreferences) == 0 { - return defaultCurvePreferences - } - return c.CurvePreferences -} - -func (c *config) supportsCurve(curve CurveID) bool { - for _, cc := range c.curvePreferences() { - if cc == curve { - return true - } - } - return false -} - -// mutualVersion returns the protocol version to use given the advertised -// versions of the peer. Priority is given to the peer preference order. -func (c *config) mutualVersion(peerVersions []uint16) (uint16, bool) { - supportedVersions := c.supportedVersions() - for _, peerVersion := range peerVersions { - for _, v := range supportedVersions { - if v == peerVersion { - return v, true - } - } - } - return 0, false -} - -var errNoCertificates = errors.New("tls: no certificates configured") - -// getCertificate returns the best certificate for the given ClientHelloInfo, -// defaulting to the first element of c.Certificates. -func (c *config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) { - if c.GetCertificate != nil && - (len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) { - cert, err := c.GetCertificate(clientHello) - if cert != nil || err != nil { - return cert, err - } - } - - if len(c.Certificates) == 0 { - return nil, errNoCertificates - } - - if len(c.Certificates) == 1 { - // There's only one choice, so no point doing any work. - return &c.Certificates[0], nil - } - - if c.NameToCertificate != nil { - name := strings.ToLower(clientHello.ServerName) - if cert, ok := c.NameToCertificate[name]; ok { - return cert, nil - } - if len(name) > 0 { - labels := strings.Split(name, ".") - labels[0] = "*" - wildcardName := strings.Join(labels, ".") - if cert, ok := c.NameToCertificate[wildcardName]; ok { - return cert, nil - } - } - } - - for _, cert := range c.Certificates { - if err := clientHello.SupportsCertificate(&cert); err == nil { - return &cert, nil - } - } - - // If nothing matches, return the first certificate. - return &c.Certificates[0], nil -} - -// SupportsCertificate returns nil if the provided certificate is supported by -// the client that sent the ClientHello. Otherwise, it returns an error -// describing the reason for the incompatibility. -// -// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate -// callback, this method will take into account the associated Config. Note that -// if GetConfigForClient returns a different Config, the change can't be -// accounted for by this method. -// -// This function will call x509.ParseCertificate unless c.Leaf is set, which can -// incur a significant performance cost. -func (chi *clientHelloInfo) SupportsCertificate(c *Certificate) error { - // Note we don't currently support certificate_authorities nor - // signature_algorithms_cert, and don't check the algorithms of the - // signatures on the chain (which anyway are a SHOULD, see RFC 8446, - // Section 4.4.2.2). - - config := chi.config - if config == nil { - config = &Config{} - } - conf := fromConfig(config) - vers, ok := conf.mutualVersion(chi.SupportedVersions) - if !ok { - return errors.New("no mutually supported protocol versions") - } - - // If the client specified the name they are trying to connect to, the - // certificate needs to be valid for it. - if chi.ServerName != "" { - x509Cert, err := leafCertificate(c) - if err != nil { - return fmt.Errorf("failed to parse certificate: %w", err) - } - if err := x509Cert.VerifyHostname(chi.ServerName); err != nil { - return fmt.Errorf("certificate is not valid for requested server name: %w", err) - } - } - - // supportsRSAFallback returns nil if the certificate and connection support - // the static RSA key exchange, and unsupported otherwise. The logic for - // supporting static RSA is completely disjoint from the logic for - // supporting signed key exchanges, so we just check it as a fallback. - supportsRSAFallback := func(unsupported error) error { - // TLS 1.3 dropped support for the static RSA key exchange. - if vers == VersionTLS13 { - return unsupported - } - // The static RSA key exchange works by decrypting a challenge with the - // RSA private key, not by signing, so check the PrivateKey implements - // crypto.Decrypter, like *rsa.PrivateKey does. - if priv, ok := c.PrivateKey.(crypto.Decrypter); ok { - if _, ok := priv.Public().(*rsa.PublicKey); !ok { - return unsupported - } - } else { - return unsupported - } - // Finally, there needs to be a mutual cipher suite that uses the static - // RSA key exchange instead of ECDHE. - rsaCipherSuite := selectCipherSuite(chi.CipherSuites, conf.cipherSuites(), func(c *cipherSuite) bool { - if c.flags&suiteECDHE != 0 { - return false - } - if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { - return false - } - return true - }) - if rsaCipherSuite == nil { - return unsupported - } - return nil - } - - // If the client sent the signature_algorithms extension, ensure it supports - // schemes we can use with this certificate and TLS version. - if len(chi.SignatureSchemes) > 0 { - if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil { - return supportsRSAFallback(err) - } - } - - // In TLS 1.3 we are done because supported_groups is only relevant to the - // ECDHE computation, point format negotiation is removed, cipher suites are - // only relevant to the AEAD choice, and static RSA does not exist. - if vers == VersionTLS13 { - return nil - } - - // The only signed key exchange we support is ECDHE. - if !supportsECDHE(conf, chi.SupportedCurves, chi.SupportedPoints) { - return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange")) - } - - var ecdsaCipherSuite bool - if priv, ok := c.PrivateKey.(crypto.Signer); ok { - switch pub := priv.Public().(type) { - case *ecdsa.PublicKey: - var curve CurveID - switch pub.Curve { - case elliptic.P256(): - curve = CurveP256 - case elliptic.P384(): - curve = CurveP384 - case elliptic.P521(): - curve = CurveP521 - default: - return supportsRSAFallback(unsupportedCertificateError(c)) - } - var curveOk bool - for _, c := range chi.SupportedCurves { - if c == curve && conf.supportsCurve(c) { - curveOk = true - break - } - } - if !curveOk { - return errors.New("client doesn't support certificate curve") - } - ecdsaCipherSuite = true - case ed25519.PublicKey: - if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 { - return errors.New("connection doesn't support Ed25519") - } - ecdsaCipherSuite = true - case *rsa.PublicKey: - default: - return supportsRSAFallback(unsupportedCertificateError(c)) - } - } else { - return supportsRSAFallback(unsupportedCertificateError(c)) - } - - // Make sure that there is a mutually supported cipher suite that works with - // this certificate. Cipher suite selection will then apply the logic in - // reverse to pick it. See also serverHandshakeState.cipherSuiteOk. - cipherSuite := selectCipherSuite(chi.CipherSuites, conf.cipherSuites(), func(c *cipherSuite) bool { - if c.flags&suiteECDHE == 0 { - return false - } - if c.flags&suiteECSign != 0 { - if !ecdsaCipherSuite { - return false - } - } else { - if ecdsaCipherSuite { - return false - } - } - if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { - return false - } - return true - }) - if cipherSuite == nil { - return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate")) - } - - return nil -} - -// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate -// from the CommonName and SubjectAlternateName fields of each of the leaf -// certificates. -// -// Deprecated: NameToCertificate only allows associating a single certificate -// with a given name. Leave that field nil to let the library select the first -// compatible chain from Certificates. -func (c *config) BuildNameToCertificate() { - c.NameToCertificate = make(map[string]*Certificate) - for i := range c.Certificates { - cert := &c.Certificates[i] - x509Cert, err := leafCertificate(cert) - if err != nil { - continue - } - // If SANs are *not* present, some clients will consider the certificate - // valid for the name in the Common Name. - if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 { - c.NameToCertificate[x509Cert.Subject.CommonName] = cert - } - for _, san := range x509Cert.DNSNames { - c.NameToCertificate[san] = cert - } - } -} - -const ( - keyLogLabelTLS12 = "CLIENT_RANDOM" - keyLogLabelEarlyTraffic = "CLIENT_EARLY_TRAFFIC_SECRET" - keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET" - keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET" - keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0" - keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0" -) - -func (c *config) writeKeyLog(label string, clientRandom, secret []byte) error { - if c.KeyLogWriter == nil { - return nil - } - - logLine := []byte(fmt.Sprintf("%s %x %x\n", label, clientRandom, secret)) - - writerMutex.Lock() - _, err := c.KeyLogWriter.Write(logLine) - writerMutex.Unlock() - - return err -} - -// writerMutex protects all KeyLogWriters globally. It is rarely enabled, -// and is only for debugging, so a global mutex saves space. -var writerMutex sync.Mutex - -// A Certificate is a chain of one or more certificates, leaf first. -type Certificate = tls.Certificate - -// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing -// the corresponding c.Certificate[0]. -func leafCertificate(c *Certificate) (*x509.Certificate, error) { - if c.Leaf != nil { - return c.Leaf, nil - } - return x509.ParseCertificate(c.Certificate[0]) -} - -type handshakeMessage interface { - marshal() []byte - unmarshal([]byte) bool -} - -// lruSessionCache is a ClientSessionCache implementation that uses an LRU -// caching strategy. -type lruSessionCache struct { - sync.Mutex - - m map[string]*list.Element - q *list.List - capacity int -} - -type lruSessionCacheEntry struct { - sessionKey string - state *ClientSessionState -} - -// NewLRUClientSessionCache returns a ClientSessionCache with the given -// capacity that uses an LRU strategy. If capacity is < 1, a default capacity -// is used instead. -func NewLRUClientSessionCache(capacity int) ClientSessionCache { - const defaultSessionCacheCapacity = 64 - - if capacity < 1 { - capacity = defaultSessionCacheCapacity - } - return &lruSessionCache{ - m: make(map[string]*list.Element), - q: list.New(), - capacity: capacity, - } -} - -// Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry -// corresponding to sessionKey is removed from the cache instead. -func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) { - c.Lock() - defer c.Unlock() - - if elem, ok := c.m[sessionKey]; ok { - if cs == nil { - c.q.Remove(elem) - delete(c.m, sessionKey) - } else { - entry := elem.Value.(*lruSessionCacheEntry) - entry.state = cs - c.q.MoveToFront(elem) - } - return - } - - if c.q.Len() < c.capacity { - entry := &lruSessionCacheEntry{sessionKey, cs} - c.m[sessionKey] = c.q.PushFront(entry) - return - } - - elem := c.q.Back() - entry := elem.Value.(*lruSessionCacheEntry) - delete(c.m, entry.sessionKey) - entry.sessionKey = sessionKey - entry.state = cs - c.q.MoveToFront(elem) - c.m[sessionKey] = elem -} - -// Get returns the ClientSessionState value associated with a given key. It -// returns (nil, false) if no value is found. -func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) { - c.Lock() - defer c.Unlock() - - if elem, ok := c.m[sessionKey]; ok { - c.q.MoveToFront(elem) - return elem.Value.(*lruSessionCacheEntry).state, true - } - return nil, false -} - -var emptyConfig Config - -func defaultConfig() *Config { - return &emptyConfig -} - -func unexpectedMessageError(wanted, got interface{}) error { - return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted) -} - -func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool { - for _, s := range supportedSignatureAlgorithms { - if s == sigAlg { - return true - } - } - return false -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/conn.go b/vendor/github.com/marten-seemann/qtls-go1-17/conn.go deleted file mode 100644 index 70fad4652..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/conn.go +++ /dev/null @@ -1,1601 +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. - -// TLS low level connection and record layer - -package qtls - -import ( - "bytes" - "context" - "crypto/cipher" - "crypto/subtle" - "crypto/x509" - "errors" - "fmt" - "hash" - "io" - "net" - "sync" - "sync/atomic" - "time" -) - -// A Conn represents a secured connection. -// It implements the net.Conn interface. -type Conn struct { - // constant - conn net.Conn - isClient bool - handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake - - // handshakeStatus is 1 if the connection is currently transferring - // application data (i.e. is not currently processing a handshake). - // handshakeStatus == 1 implies handshakeErr == nil. - // This field is only to be accessed with sync/atomic. - handshakeStatus uint32 - // constant after handshake; protected by handshakeMutex - handshakeMutex sync.Mutex - handshakeErr error // error resulting from handshake - vers uint16 // TLS version - haveVers bool // version has been negotiated - config *config // configuration passed to constructor - // handshakes counts the number of handshakes performed on the - // connection so far. If renegotiation is disabled then this is either - // zero or one. - extraConfig *ExtraConfig - - handshakes int - didResume bool // whether this connection was a session resumption - cipherSuite uint16 - ocspResponse []byte // stapled OCSP response - scts [][]byte // signed certificate timestamps from server - peerCertificates []*x509.Certificate - // verifiedChains contains the certificate chains that we built, as - // opposed to the ones presented by the server. - verifiedChains [][]*x509.Certificate - // serverName contains the server name indicated by the client, if any. - serverName string - // secureRenegotiation is true if the server echoed the secure - // renegotiation extension. (This is meaningless as a server because - // renegotiation is not supported in that case.) - secureRenegotiation bool - // ekm is a closure for exporting keying material. - ekm func(label string, context []byte, length int) ([]byte, error) - // For the client: - // resumptionSecret is the resumption_master_secret for handling - // NewSessionTicket messages. nil if config.SessionTicketsDisabled. - // For the server: - // resumptionSecret is the resumption_master_secret for generating - // NewSessionTicket messages. Only used when the alternative record - // layer is set. nil if config.SessionTicketsDisabled. - resumptionSecret []byte - - // ticketKeys is the set of active session ticket keys for this - // connection. The first one is used to encrypt new tickets and - // all are tried to decrypt tickets. - ticketKeys []ticketKey - - // clientFinishedIsFirst is true if the client sent the first Finished - // message during the most recent handshake. This is recorded because - // the first transmitted Finished message is the tls-unique - // channel-binding value. - clientFinishedIsFirst bool - - // closeNotifyErr is any error from sending the alertCloseNotify record. - closeNotifyErr error - // closeNotifySent is true if the Conn attempted to send an - // alertCloseNotify record. - closeNotifySent bool - - // clientFinished and serverFinished contain the Finished message sent - // by the client or server in the most recent handshake. This is - // retained to support the renegotiation extension and tls-unique - // channel-binding. - clientFinished [12]byte - serverFinished [12]byte - - // clientProtocol is the negotiated ALPN protocol. - clientProtocol string - - // input/output - in, out halfConn - rawInput bytes.Buffer // raw input, starting with a record header - input bytes.Reader // application data waiting to be read, from rawInput.Next - hand bytes.Buffer // handshake data waiting to be read - buffering bool // whether records are buffered in sendBuf - sendBuf []byte // a buffer of records waiting to be sent - - // bytesSent counts the bytes of application data sent. - // packetsSent counts packets. - bytesSent int64 - packetsSent int64 - - // retryCount counts the number of consecutive non-advancing records - // received by Conn.readRecord. That is, records that neither advance the - // handshake, nor deliver application data. Protected by in.Mutex. - retryCount int - - // activeCall is an atomic int32; the low bit is whether Close has - // been called. the rest of the bits are the number of goroutines - // in Conn.Write. - activeCall int32 - - used0RTT bool - - tmp [16]byte -} - -// Access to net.Conn methods. -// Cannot just embed net.Conn because that would -// export the struct field too. - -// LocalAddr returns the local network address. -func (c *Conn) LocalAddr() net.Addr { - return c.conn.LocalAddr() -} - -// RemoteAddr returns the remote network address. -func (c *Conn) RemoteAddr() net.Addr { - return c.conn.RemoteAddr() -} - -// SetDeadline sets the read and write deadlines associated with the connection. -// A zero value for t means Read and Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -// SetReadDeadline sets the read deadline on the underlying connection. -// A zero value for t means Read will not time out. -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -// SetWriteDeadline sets the write deadline on the underlying connection. -// A zero value for t means Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -// A halfConn represents one direction of the record layer -// connection, either sending or receiving. -type halfConn struct { - sync.Mutex - - err error // first permanent error - version uint16 // protocol version - cipher interface{} // cipher algorithm - mac hash.Hash - seq [8]byte // 64-bit sequence number - - scratchBuf [13]byte // to avoid allocs; interface method args escape - - nextCipher interface{} // next encryption state - nextMac hash.Hash // next MAC algorithm - - trafficSecret []byte // current TLS 1.3 traffic secret - - setKeyCallback func(encLevel EncryptionLevel, suite *CipherSuiteTLS13, trafficSecret []byte) -} - -type permanentError struct { - err net.Error -} - -func (e *permanentError) Error() string { return e.err.Error() } -func (e *permanentError) Unwrap() error { return e.err } -func (e *permanentError) Timeout() bool { return e.err.Timeout() } -func (e *permanentError) Temporary() bool { return false } - -func (hc *halfConn) setErrorLocked(err error) error { - if e, ok := err.(net.Error); ok { - hc.err = &permanentError{err: e} - } else { - hc.err = err - } - return hc.err -} - -// prepareCipherSpec sets the encryption and MAC states -// that a subsequent changeCipherSpec will use. -func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac hash.Hash) { - hc.version = version - hc.nextCipher = cipher - hc.nextMac = mac -} - -// changeCipherSpec changes the encryption and MAC states -// to the ones previously passed to prepareCipherSpec. -func (hc *halfConn) changeCipherSpec() error { - if hc.nextCipher == nil || hc.version == VersionTLS13 { - return alertInternalError - } - hc.cipher = hc.nextCipher - hc.mac = hc.nextMac - hc.nextCipher = nil - hc.nextMac = nil - for i := range hc.seq { - hc.seq[i] = 0 - } - return nil -} - -func (hc *halfConn) exportKey(encLevel EncryptionLevel, suite *cipherSuiteTLS13, trafficSecret []byte) { - if hc.setKeyCallback != nil { - s := &CipherSuiteTLS13{ - ID: suite.id, - KeyLen: suite.keyLen, - Hash: suite.hash, - AEAD: func(key, fixedNonce []byte) cipher.AEAD { return suite.aead(key, fixedNonce) }, - } - hc.setKeyCallback(encLevel, s, trafficSecret) - } -} - -func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, secret []byte) { - hc.trafficSecret = secret - key, iv := suite.trafficKey(secret) - hc.cipher = suite.aead(key, iv) - for i := range hc.seq { - hc.seq[i] = 0 - } -} - -// incSeq increments the sequence number. -func (hc *halfConn) incSeq() { - for i := 7; i >= 0; i-- { - hc.seq[i]++ - if hc.seq[i] != 0 { - return - } - } - - // Not allowed to let sequence number wrap. - // Instead, must renegotiate before it does. - // Not likely enough to bother. - panic("TLS: sequence number wraparound") -} - -// explicitNonceLen returns the number of bytes of explicit nonce or IV included -// in each record. Explicit nonces are present only in CBC modes after TLS 1.0 -// and in certain AEAD modes in TLS 1.2. -func (hc *halfConn) explicitNonceLen() int { - if hc.cipher == nil { - return 0 - } - - switch c := hc.cipher.(type) { - case cipher.Stream: - return 0 - case aead: - return c.explicitNonceLen() - case cbcMode: - // TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack. - if hc.version >= VersionTLS11 { - return c.BlockSize() - } - return 0 - default: - panic("unknown cipher type") - } -} - -// extractPadding returns, in constant time, the length of the padding to remove -// from the end of payload. It also returns a byte which is equal to 255 if the -// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2. -func extractPadding(payload []byte) (toRemove int, good byte) { - if len(payload) < 1 { - return 0, 0 - } - - paddingLen := payload[len(payload)-1] - t := uint(len(payload)-1) - uint(paddingLen) - // if len(payload) >= (paddingLen - 1) then the MSB of t is zero - good = byte(int32(^t) >> 31) - - // The maximum possible padding length plus the actual length field - toCheck := 256 - // The length of the padded data is public, so we can use an if here - if toCheck > len(payload) { - toCheck = len(payload) - } - - for i := 0; i < toCheck; i++ { - t := uint(paddingLen) - uint(i) - // if i <= paddingLen then the MSB of t is zero - mask := byte(int32(^t) >> 31) - b := payload[len(payload)-1-i] - good &^= mask&paddingLen ^ mask&b - } - - // We AND together the bits of good and replicate the result across - // all the bits. - good &= good << 4 - good &= good << 2 - good &= good << 1 - good = uint8(int8(good) >> 7) - - // Zero the padding length on error. This ensures any unchecked bytes - // are included in the MAC. Otherwise, an attacker that could - // distinguish MAC failures from padding failures could mount an attack - // similar to POODLE in SSL 3.0: given a good ciphertext that uses a - // full block's worth of padding, replace the final block with another - // block. If the MAC check passed but the padding check failed, the - // last byte of that block decrypted to the block size. - // - // See also macAndPaddingGood logic below. - paddingLen &= good - - toRemove = int(paddingLen) + 1 - return -} - -func roundUp(a, b int) int { - return a + (b-a%b)%b -} - -// cbcMode is an interface for block ciphers using cipher block chaining. -type cbcMode interface { - cipher.BlockMode - SetIV([]byte) -} - -// decrypt authenticates and decrypts the record if protection is active at -// this stage. The returned plaintext might overlap with the input. -func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) { - var plaintext []byte - typ := recordType(record[0]) - payload := record[recordHeaderLen:] - - // In TLS 1.3, change_cipher_spec messages are to be ignored without being - // decrypted. See RFC 8446, Appendix D.4. - if hc.version == VersionTLS13 && typ == recordTypeChangeCipherSpec { - return payload, typ, nil - } - - paddingGood := byte(255) - paddingLen := 0 - - explicitNonceLen := hc.explicitNonceLen() - - if hc.cipher != nil { - switch c := hc.cipher.(type) { - case cipher.Stream: - c.XORKeyStream(payload, payload) - case aead: - if len(payload) < explicitNonceLen { - return nil, 0, alertBadRecordMAC - } - nonce := payload[:explicitNonceLen] - if len(nonce) == 0 { - nonce = hc.seq[:] - } - payload = payload[explicitNonceLen:] - - var additionalData []byte - if hc.version == VersionTLS13 { - additionalData = record[:recordHeaderLen] - } else { - additionalData = append(hc.scratchBuf[:0], hc.seq[:]...) - additionalData = append(additionalData, record[:3]...) - n := len(payload) - c.Overhead() - additionalData = append(additionalData, byte(n>>8), byte(n)) - } - - var err error - plaintext, err = c.Open(payload[:0], nonce, payload, additionalData) - if err != nil { - return nil, 0, alertBadRecordMAC - } - case cbcMode: - blockSize := c.BlockSize() - minPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize) - if len(payload)%blockSize != 0 || len(payload) < minPayload { - return nil, 0, alertBadRecordMAC - } - - if explicitNonceLen > 0 { - c.SetIV(payload[:explicitNonceLen]) - payload = payload[explicitNonceLen:] - } - c.CryptBlocks(payload, payload) - - // In a limited attempt to protect against CBC padding oracles like - // Lucky13, the data past paddingLen (which is secret) is passed to - // the MAC function as extra data, to be fed into the HMAC after - // computing the digest. This makes the MAC roughly constant time as - // long as the digest computation is constant time and does not - // affect the subsequent write, modulo cache effects. - paddingLen, paddingGood = extractPadding(payload) - default: - panic("unknown cipher type") - } - - if hc.version == VersionTLS13 { - if typ != recordTypeApplicationData { - return nil, 0, alertUnexpectedMessage - } - if len(plaintext) > maxPlaintext+1 { - return nil, 0, alertRecordOverflow - } - // Remove padding and find the ContentType scanning from the end. - for i := len(plaintext) - 1; i >= 0; i-- { - if plaintext[i] != 0 { - typ = recordType(plaintext[i]) - plaintext = plaintext[:i] - break - } - if i == 0 { - return nil, 0, alertUnexpectedMessage - } - } - } - } else { - plaintext = payload - } - - if hc.mac != nil { - macSize := hc.mac.Size() - if len(payload) < macSize { - return nil, 0, alertBadRecordMAC - } - - n := len(payload) - macSize - paddingLen - n = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 } - record[3] = byte(n >> 8) - record[4] = byte(n) - remoteMAC := payload[n : n+macSize] - localMAC := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload[:n], payload[n+macSize:]) - - // This is equivalent to checking the MACs and paddingGood - // separately, but in constant-time to prevent distinguishing - // padding failures from MAC failures. Depending on what value - // of paddingLen was returned on bad padding, distinguishing - // bad MAC from bad padding can lead to an attack. - // - // See also the logic at the end of extractPadding. - macAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood) - if macAndPaddingGood != 1 { - return nil, 0, alertBadRecordMAC - } - - plaintext = payload[:n] - } - - hc.incSeq() - return plaintext, typ, nil -} - -func (c *Conn) setAlternativeRecordLayer() { - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - c.in.setKeyCallback = c.extraConfig.AlternativeRecordLayer.SetReadKey - c.out.setKeyCallback = c.extraConfig.AlternativeRecordLayer.SetWriteKey - } -} - -// sliceForAppend extends the input slice by n bytes. head is the full extended -// slice, while tail is the appended part. If the original slice has sufficient -// capacity 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 -} - -// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and -// appends it to record, which must already contain the record header. -func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) { - if hc.cipher == nil { - return append(record, payload...), nil - } - - var explicitNonce []byte - if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 { - record, explicitNonce = sliceForAppend(record, explicitNonceLen) - if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 { - // The AES-GCM construction in TLS has an explicit nonce so that the - // nonce can be random. However, the nonce is only 8 bytes which is - // too small for a secure, random nonce. Therefore we use the - // sequence number as the nonce. The 3DES-CBC construction also has - // an 8 bytes nonce but its nonces must be unpredictable (see RFC - // 5246, Appendix F.3), forcing us to use randomness. That's not - // 3DES' biggest problem anyway because the birthday bound on block - // collision is reached first due to its similarly small block size - // (see the Sweet32 attack). - copy(explicitNonce, hc.seq[:]) - } else { - if _, err := io.ReadFull(rand, explicitNonce); err != nil { - return nil, err - } - } - } - - var dst []byte - switch c := hc.cipher.(type) { - case cipher.Stream: - mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil) - record, dst = sliceForAppend(record, len(payload)+len(mac)) - c.XORKeyStream(dst[:len(payload)], payload) - c.XORKeyStream(dst[len(payload):], mac) - case aead: - nonce := explicitNonce - if len(nonce) == 0 { - nonce = hc.seq[:] - } - - if hc.version == VersionTLS13 { - record = append(record, payload...) - - // Encrypt the actual ContentType and replace the plaintext one. - record = append(record, record[0]) - record[0] = byte(recordTypeApplicationData) - - n := len(payload) + 1 + c.Overhead() - record[3] = byte(n >> 8) - record[4] = byte(n) - - record = c.Seal(record[:recordHeaderLen], - nonce, record[recordHeaderLen:], record[:recordHeaderLen]) - } else { - additionalData := append(hc.scratchBuf[:0], hc.seq[:]...) - additionalData = append(additionalData, record[:recordHeaderLen]...) - record = c.Seal(record, nonce, payload, additionalData) - } - case cbcMode: - mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil) - blockSize := c.BlockSize() - plaintextLen := len(payload) + len(mac) - paddingLen := blockSize - plaintextLen%blockSize - record, dst = sliceForAppend(record, plaintextLen+paddingLen) - copy(dst, payload) - copy(dst[len(payload):], mac) - for i := plaintextLen; i < len(dst); i++ { - dst[i] = byte(paddingLen - 1) - } - if len(explicitNonce) > 0 { - c.SetIV(explicitNonce) - } - c.CryptBlocks(dst, dst) - default: - panic("unknown cipher type") - } - - // Update length to include nonce, MAC and any block padding needed. - n := len(record) - recordHeaderLen - record[3] = byte(n >> 8) - record[4] = byte(n) - hc.incSeq() - - return record, nil -} - -// RecordHeaderError is returned when a TLS record header is invalid. -type RecordHeaderError struct { - // Msg contains a human readable string that describes the error. - Msg string - // RecordHeader contains the five bytes of TLS record header that - // triggered the error. - RecordHeader [5]byte - // Conn provides the underlying net.Conn in the case that a client - // sent an initial handshake that didn't look like TLS. - // It is nil if there's already been a handshake or a TLS alert has - // been written to the connection. - Conn net.Conn -} - -func (e RecordHeaderError) Error() string { return "tls: " + e.Msg } - -func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) { - err.Msg = msg - err.Conn = conn - copy(err.RecordHeader[:], c.rawInput.Bytes()) - return err -} - -func (c *Conn) readRecord() error { - return c.readRecordOrCCS(false) -} - -func (c *Conn) readChangeCipherSpec() error { - return c.readRecordOrCCS(true) -} - -// readRecordOrCCS reads one or more TLS records from the connection and -// updates the record layer state. Some invariants: -// * c.in must be locked -// * c.input must be empty -// During the handshake one and only one of the following will happen: -// - c.hand grows -// - c.in.changeCipherSpec is called -// - an error is returned -// After the handshake one and only one of the following will happen: -// - c.hand grows -// - c.input is set -// - an error is returned -func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error { - if c.in.err != nil { - return c.in.err - } - handshakeComplete := c.handshakeComplete() - - // This function modifies c.rawInput, which owns the c.input memory. - if c.input.Len() != 0 { - return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data")) - } - c.input.Reset(nil) - - // Read header, payload. - if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil { - // RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify - // is an error, but popular web sites seem to do this, so we accept it - // if and only if at the record boundary. - if err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 { - err = io.EOF - } - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.in.setErrorLocked(err) - } - return err - } - hdr := c.rawInput.Bytes()[:recordHeaderLen] - typ := recordType(hdr[0]) - - // No valid TLS record has a type of 0x80, however SSLv2 handshakes - // start with a uint16 length where the MSB is set and the first record - // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests - // an SSLv2 client. - if !handshakeComplete && typ == 0x80 { - c.sendAlert(alertProtocolVersion) - return c.in.setErrorLocked(c.newRecordHeaderError(nil, "unsupported SSLv2 handshake received")) - } - - vers := uint16(hdr[1])<<8 | uint16(hdr[2]) - n := int(hdr[3])<<8 | int(hdr[4]) - if c.haveVers && c.vers != VersionTLS13 && vers != c.vers { - c.sendAlert(alertProtocolVersion) - msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, c.vers) - return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg)) - } - if !c.haveVers { - // First message, be extra suspicious: this might not be a TLS - // client. Bail out before reading a full 'body', if possible. - // The current max version is 3.3 so if the version is >= 16.0, - // it's probably not real. - if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 { - return c.in.setErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake")) - } - } - if c.vers == VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext { - c.sendAlert(alertRecordOverflow) - msg := fmt.Sprintf("oversized record received with length %d", n) - return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg)) - } - if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil { - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.in.setErrorLocked(err) - } - return err - } - - // Process message. - record := c.rawInput.Next(recordHeaderLen + n) - data, typ, err := c.in.decrypt(record) - if err != nil { - return c.in.setErrorLocked(c.sendAlert(err.(alert))) - } - if len(data) > maxPlaintext { - return c.in.setErrorLocked(c.sendAlert(alertRecordOverflow)) - } - - // Application Data messages are always protected. - if c.in.cipher == nil && typ == recordTypeApplicationData { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 { - // This is a state-advancing message: reset the retry count. - c.retryCount = 0 - } - - // Handshake messages MUST NOT be interleaved with other record types in TLS 1.3. - if c.vers == VersionTLS13 && typ != recordTypeHandshake && c.hand.Len() > 0 { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - switch typ { - default: - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - - case recordTypeAlert: - if len(data) != 2 { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - if alert(data[1]) == alertCloseNotify { - return c.in.setErrorLocked(io.EOF) - } - if c.vers == VersionTLS13 { - return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])}) - } - switch data[0] { - case alertLevelWarning: - // Drop the record on the floor and retry. - return c.retryReadRecord(expectChangeCipherSpec) - case alertLevelError: - return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])}) - default: - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - case recordTypeChangeCipherSpec: - if len(data) != 1 || data[0] != 1 { - return c.in.setErrorLocked(c.sendAlert(alertDecodeError)) - } - // Handshake messages are not allowed to fragment across the CCS. - if c.hand.Len() > 0 { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - // In TLS 1.3, change_cipher_spec records are ignored until the - // Finished. See RFC 8446, Appendix D.4. Note that according to Section - // 5, a server can send a ChangeCipherSpec before its ServerHello, when - // c.vers is still unset. That's not useful though and suspicious if the - // server then selects a lower protocol version, so don't allow that. - if c.vers == VersionTLS13 { - return c.retryReadRecord(expectChangeCipherSpec) - } - if !expectChangeCipherSpec { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - if err := c.in.changeCipherSpec(); err != nil { - return c.in.setErrorLocked(c.sendAlert(err.(alert))) - } - - case recordTypeApplicationData: - if !handshakeComplete || expectChangeCipherSpec { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - // Some OpenSSL servers send empty records in order to randomize the - // CBC IV. Ignore a limited number of empty records. - if len(data) == 0 { - return c.retryReadRecord(expectChangeCipherSpec) - } - // Note that data is owned by c.rawInput, following the Next call above, - // to avoid copying the plaintext. This is safe because c.rawInput is - // not read from or written to until c.input is drained. - c.input.Reset(data) - - case recordTypeHandshake: - if len(data) == 0 || expectChangeCipherSpec { - return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - c.hand.Write(data) - } - - return nil -} - -// retryReadRecord recurses into readRecordOrCCS to drop a non-advancing record, like -// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3. -func (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error { - c.retryCount++ - if c.retryCount > maxUselessRecords { - c.sendAlert(alertUnexpectedMessage) - return c.in.setErrorLocked(errors.New("tls: too many ignored records")) - } - return c.readRecordOrCCS(expectChangeCipherSpec) -} - -// atLeastReader reads from R, stopping with EOF once at least N bytes have been -// read. It is different from an io.LimitedReader in that it doesn't cut short -// the last Read call, and in that it considers an early EOF an error. -type atLeastReader struct { - R io.Reader - N int64 -} - -func (r *atLeastReader) Read(p []byte) (int, error) { - if r.N <= 0 { - return 0, io.EOF - } - n, err := r.R.Read(p) - r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809 - if r.N > 0 && err == io.EOF { - return n, io.ErrUnexpectedEOF - } - if r.N <= 0 && err == nil { - return n, io.EOF - } - return n, err -} - -// readFromUntil reads from r into c.rawInput until c.rawInput contains -// at least n bytes or else returns an error. -func (c *Conn) readFromUntil(r io.Reader, n int) error { - if c.rawInput.Len() >= n { - return nil - } - needs := n - c.rawInput.Len() - // There might be extra input waiting on the wire. Make a best effort - // attempt to fetch it so that it can be used in (*Conn).Read to - // "predict" closeNotify alerts. - c.rawInput.Grow(needs + bytes.MinRead) - _, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)}) - return err -} - -// sendAlert sends a TLS alert message. -func (c *Conn) sendAlertLocked(err alert) error { - switch err { - case alertNoRenegotiation, alertCloseNotify: - c.tmp[0] = alertLevelWarning - default: - c.tmp[0] = alertLevelError - } - c.tmp[1] = byte(err) - - _, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2]) - if err == alertCloseNotify { - // closeNotify is a special case in that it isn't an error. - return writeErr - } - - return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err}) -} - -// sendAlert sends a TLS alert message. -func (c *Conn) sendAlert(err alert) error { - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - c.extraConfig.AlternativeRecordLayer.SendAlert(uint8(err)) - return &net.OpError{Op: "local error", Err: err} - } - - c.out.Lock() - defer c.out.Unlock() - return c.sendAlertLocked(err) -} - -const ( - // tcpMSSEstimate is a conservative estimate of the TCP maximum segment - // size (MSS). A constant is used, rather than querying the kernel for - // the actual MSS, to avoid complexity. The value here is the IPv6 - // minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40 - // bytes) and a TCP header with timestamps (32 bytes). - tcpMSSEstimate = 1208 - - // recordSizeBoostThreshold is the number of bytes of application data - // sent after which the TLS record size will be increased to the - // maximum. - recordSizeBoostThreshold = 128 * 1024 -) - -// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the -// next application data record. There is the following trade-off: -// -// - For latency-sensitive applications, such as web browsing, each TLS -// record should fit in one TCP segment. -// - For throughput-sensitive applications, such as large file transfers, -// larger TLS records better amortize framing and encryption overheads. -// -// A simple heuristic that works well in practice is to use small records for -// the first 1MB of data, then use larger records for subsequent data, and -// reset back to smaller records after the connection becomes idle. See "High -// Performance Web Networking", Chapter 4, or: -// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/ -// -// In the interests of simplicity and determinism, this code does not attempt -// to reset the record size once the connection is idle, however. -func (c *Conn) maxPayloadSizeForWrite(typ recordType) int { - if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData { - return maxPlaintext - } - - if c.bytesSent >= recordSizeBoostThreshold { - return maxPlaintext - } - - // Subtract TLS overheads to get the maximum payload size. - payloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen() - if c.out.cipher != nil { - switch ciph := c.out.cipher.(type) { - case cipher.Stream: - payloadBytes -= c.out.mac.Size() - case cipher.AEAD: - payloadBytes -= ciph.Overhead() - case cbcMode: - blockSize := ciph.BlockSize() - // The payload must fit in a multiple of blockSize, with - // room for at least one padding byte. - payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1 - // The MAC is appended before padding so affects the - // payload size directly. - payloadBytes -= c.out.mac.Size() - default: - panic("unknown cipher type") - } - } - if c.vers == VersionTLS13 { - payloadBytes-- // encrypted ContentType - } - - // Allow packet growth in arithmetic progression up to max. - pkt := c.packetsSent - c.packetsSent++ - if pkt > 1000 { - return maxPlaintext // avoid overflow in multiply below - } - - n := payloadBytes * int(pkt+1) - if n > maxPlaintext { - n = maxPlaintext - } - return n -} - -func (c *Conn) write(data []byte) (int, error) { - if c.buffering { - c.sendBuf = append(c.sendBuf, data...) - return len(data), nil - } - - n, err := c.conn.Write(data) - c.bytesSent += int64(n) - return n, err -} - -func (c *Conn) flush() (int, error) { - if len(c.sendBuf) == 0 { - return 0, nil - } - - n, err := c.conn.Write(c.sendBuf) - c.bytesSent += int64(n) - c.sendBuf = nil - c.buffering = false - return n, err -} - -// outBufPool pools the record-sized scratch buffers used by writeRecordLocked. -var outBufPool = sync.Pool{ - New: func() interface{} { - return new([]byte) - }, -} - -// writeRecordLocked writes a TLS record with the given type and payload to the -// connection and updates the record layer state. -func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) { - outBufPtr := outBufPool.Get().(*[]byte) - outBuf := *outBufPtr - defer func() { - // You might be tempted to simplify this by just passing &outBuf to Put, - // but that would make the local copy of the outBuf slice header escape - // to the heap, causing an allocation. Instead, we keep around the - // pointer to the slice header returned by Get, which is already on the - // heap, and overwrite and return that. - *outBufPtr = outBuf - outBufPool.Put(outBufPtr) - }() - - var n int - for len(data) > 0 { - m := len(data) - if maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload { - m = maxPayload - } - - _, outBuf = sliceForAppend(outBuf[:0], recordHeaderLen) - outBuf[0] = byte(typ) - vers := c.vers - if vers == 0 { - // Some TLS servers fail if the record version is - // greater than TLS 1.0 for the initial ClientHello. - vers = VersionTLS10 - } else if vers == VersionTLS13 { - // TLS 1.3 froze the record layer version to 1.2. - // See RFC 8446, Section 5.1. - vers = VersionTLS12 - } - outBuf[1] = byte(vers >> 8) - outBuf[2] = byte(vers) - outBuf[3] = byte(m >> 8) - outBuf[4] = byte(m) - - var err error - outBuf, err = c.out.encrypt(outBuf, data[:m], c.config.rand()) - if err != nil { - return n, err - } - if _, err := c.write(outBuf); err != nil { - return n, err - } - n += m - data = data[m:] - } - - if typ == recordTypeChangeCipherSpec && c.vers != VersionTLS13 { - if err := c.out.changeCipherSpec(); err != nil { - return n, c.sendAlertLocked(err.(alert)) - } - } - - return n, nil -} - -// writeRecord writes a TLS record with the given type and payload to the -// connection and updates the record layer state. -func (c *Conn) writeRecord(typ recordType, data []byte) (int, error) { - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - if typ == recordTypeChangeCipherSpec { - return len(data), nil - } - return c.extraConfig.AlternativeRecordLayer.WriteRecord(data) - } - - c.out.Lock() - defer c.out.Unlock() - - return c.writeRecordLocked(typ, data) -} - -// readHandshake reads the next handshake message from -// the record layer. -func (c *Conn) readHandshake() (interface{}, error) { - var data []byte - if c.extraConfig != nil && c.extraConfig.AlternativeRecordLayer != nil { - var err error - data, err = c.extraConfig.AlternativeRecordLayer.ReadHandshakeMessage() - if err != nil { - return nil, err - } - } else { - for c.hand.Len() < 4 { - if err := c.readRecord(); err != nil { - return nil, err - } - } - - data = c.hand.Bytes() - n := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if n > maxHandshake { - c.sendAlertLocked(alertInternalError) - return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)) - } - for c.hand.Len() < 4+n { - if err := c.readRecord(); err != nil { - return nil, err - } - } - data = c.hand.Next(4 + n) - } - var m handshakeMessage - switch data[0] { - case typeHelloRequest: - m = new(helloRequestMsg) - case typeClientHello: - m = new(clientHelloMsg) - case typeServerHello: - m = new(serverHelloMsg) - case typeNewSessionTicket: - if c.vers == VersionTLS13 { - m = new(newSessionTicketMsgTLS13) - } else { - m = new(newSessionTicketMsg) - } - case typeCertificate: - if c.vers == VersionTLS13 { - m = new(certificateMsgTLS13) - } else { - m = new(certificateMsg) - } - case typeCertificateRequest: - if c.vers == VersionTLS13 { - m = new(certificateRequestMsgTLS13) - } else { - m = &certificateRequestMsg{ - hasSignatureAlgorithm: c.vers >= VersionTLS12, - } - } - case typeCertificateStatus: - m = new(certificateStatusMsg) - case typeServerKeyExchange: - m = new(serverKeyExchangeMsg) - case typeServerHelloDone: - m = new(serverHelloDoneMsg) - case typeClientKeyExchange: - m = new(clientKeyExchangeMsg) - case typeCertificateVerify: - m = &certificateVerifyMsg{ - hasSignatureAlgorithm: c.vers >= VersionTLS12, - } - case typeFinished: - m = new(finishedMsg) - case typeEncryptedExtensions: - m = new(encryptedExtensionsMsg) - case typeEndOfEarlyData: - m = new(endOfEarlyDataMsg) - case typeKeyUpdate: - m = new(keyUpdateMsg) - default: - return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - - // The handshake message unmarshalers - // expect to be able to keep references to data, - // so pass in a fresh copy that won't be overwritten. - data = append([]byte(nil), data...) - - if !m.unmarshal(data) { - return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage)) - } - return m, nil -} - -var ( - errShutdown = errors.New("tls: protocol is shutdown") -) - -// Write writes data to the connection. -// -// As Write calls Handshake, in order to prevent indefinite blocking a deadline -// must be set for both Read and Write before Write is called when the handshake -// has not yet completed. See SetDeadline, SetReadDeadline, and -// SetWriteDeadline. -func (c *Conn) Write(b []byte) (int, error) { - // interlock with Close below - for { - x := atomic.LoadInt32(&c.activeCall) - if x&1 != 0 { - return 0, net.ErrClosed - } - if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) { - break - } - } - defer atomic.AddInt32(&c.activeCall, -2) - - if err := c.Handshake(); err != nil { - return 0, err - } - - c.out.Lock() - defer c.out.Unlock() - - if err := c.out.err; err != nil { - return 0, err - } - - if !c.handshakeComplete() { - return 0, alertInternalError - } - - if c.closeNotifySent { - return 0, errShutdown - } - - // TLS 1.0 is susceptible to a chosen-plaintext - // attack when using block mode ciphers due to predictable IVs. - // This can be prevented by splitting each Application Data - // record into two records, effectively randomizing the IV. - // - // https://www.openssl.org/~bodo/tls-cbc.txt - // https://bugzilla.mozilla.org/show_bug.cgi?id=665814 - // https://www.imperialviolet.org/2012/01/15/beastfollowup.html - - var m int - if len(b) > 1 && c.vers == VersionTLS10 { - if _, ok := c.out.cipher.(cipher.BlockMode); ok { - n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1]) - if err != nil { - return n, c.out.setErrorLocked(err) - } - m, b = 1, b[1:] - } - } - - n, err := c.writeRecordLocked(recordTypeApplicationData, b) - return n + m, c.out.setErrorLocked(err) -} - -// handleRenegotiation processes a HelloRequest handshake message. -func (c *Conn) handleRenegotiation() error { - if c.vers == VersionTLS13 { - return errors.New("tls: internal error: unexpected renegotiation") - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - helloReq, ok := msg.(*helloRequestMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(helloReq, msg) - } - - if !c.isClient { - return c.sendAlert(alertNoRenegotiation) - } - - switch c.config.Renegotiation { - case RenegotiateNever: - return c.sendAlert(alertNoRenegotiation) - case RenegotiateOnceAsClient: - if c.handshakes > 1 { - return c.sendAlert(alertNoRenegotiation) - } - case RenegotiateFreelyAsClient: - // Ok. - default: - c.sendAlert(alertInternalError) - return errors.New("tls: unknown Renegotiation value") - } - - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - atomic.StoreUint32(&c.handshakeStatus, 0) - if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil { - c.handshakes++ - } - return c.handshakeErr -} - -func (c *Conn) HandlePostHandshakeMessage() error { - return c.handlePostHandshakeMessage() -} - -// handlePostHandshakeMessage processes a handshake message arrived after the -// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation. -func (c *Conn) handlePostHandshakeMessage() error { - if c.vers != VersionTLS13 { - return c.handleRenegotiation() - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - c.retryCount++ - if c.retryCount > maxUselessRecords { - c.sendAlert(alertUnexpectedMessage) - return c.in.setErrorLocked(errors.New("tls: too many non-advancing records")) - } - - switch msg := msg.(type) { - case *newSessionTicketMsgTLS13: - return c.handleNewSessionTicket(msg) - case *keyUpdateMsg: - return c.handleKeyUpdate(msg) - default: - c.sendAlert(alertUnexpectedMessage) - return fmt.Errorf("tls: received unexpected handshake message of type %T", msg) - } -} - -func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error { - cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) - if cipherSuite == nil { - return c.in.setErrorLocked(c.sendAlert(alertInternalError)) - } - - newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret) - c.in.setTrafficSecret(cipherSuite, newSecret) - - if keyUpdate.updateRequested { - c.out.Lock() - defer c.out.Unlock() - - msg := &keyUpdateMsg{} - _, err := c.writeRecordLocked(recordTypeHandshake, msg.marshal()) - if err != nil { - // Surface the error at the next write. - c.out.setErrorLocked(err) - return nil - } - - newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret) - c.out.setTrafficSecret(cipherSuite, newSecret) - } - - return nil -} - -// Read reads data from the connection. -// -// As Read calls Handshake, in order to prevent indefinite blocking a deadline -// must be set for both Read and Write before Read is called when the handshake -// has not yet completed. See SetDeadline, SetReadDeadline, and -// SetWriteDeadline. -func (c *Conn) Read(b []byte) (int, error) { - if err := c.Handshake(); err != nil { - return 0, err - } - if len(b) == 0 { - // Put this after Handshake, in case people were calling - // Read(nil) for the side effect of the Handshake. - return 0, nil - } - - c.in.Lock() - defer c.in.Unlock() - - for c.input.Len() == 0 { - if err := c.readRecord(); err != nil { - return 0, err - } - for c.hand.Len() > 0 { - if err := c.handlePostHandshakeMessage(); err != nil { - return 0, err - } - } - } - - n, _ := c.input.Read(b) - - // If a close-notify alert is waiting, read it so that we can return (n, - // EOF) instead of (n, nil), to signal to the HTTP response reading - // goroutine that the connection is now closed. This eliminates a race - // where the HTTP response reading goroutine would otherwise not observe - // the EOF until its next read, by which time a client goroutine might - // have already tried to reuse the HTTP connection for a new request. - // See https://golang.org/cl/76400046 and https://golang.org/issue/3514 - if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 && - recordType(c.rawInput.Bytes()[0]) == recordTypeAlert { - if err := c.readRecord(); err != nil { - return n, err // will be io.EOF on closeNotify - } - } - - return n, nil -} - -// Close closes the connection. -func (c *Conn) Close() error { - // Interlock with Conn.Write above. - var x int32 - for { - x = atomic.LoadInt32(&c.activeCall) - if x&1 != 0 { - return net.ErrClosed - } - if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) { - break - } - } - if x != 0 { - // io.Writer and io.Closer should not be used concurrently. - // If Close is called while a Write is currently in-flight, - // interpret that as a sign that this Close is really just - // being used to break the Write and/or clean up resources and - // avoid sending the alertCloseNotify, which may block - // waiting on handshakeMutex or the c.out mutex. - return c.conn.Close() - } - - var alertErr error - if c.handshakeComplete() { - if err := c.closeNotify(); err != nil { - alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err) - } - } - - if err := c.conn.Close(); err != nil { - return err - } - return alertErr -} - -var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete") - -// CloseWrite shuts down the writing side of the connection. It should only be -// called once the handshake has completed and does not call CloseWrite on the -// underlying connection. Most callers should just use Close. -func (c *Conn) CloseWrite() error { - if !c.handshakeComplete() { - return errEarlyCloseWrite - } - - return c.closeNotify() -} - -func (c *Conn) closeNotify() error { - c.out.Lock() - defer c.out.Unlock() - - if !c.closeNotifySent { - // Set a Write Deadline to prevent possibly blocking forever. - c.SetWriteDeadline(time.Now().Add(time.Second * 5)) - c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify) - c.closeNotifySent = true - // Any subsequent writes will fail. - c.SetWriteDeadline(time.Now()) - } - return c.closeNotifyErr -} - -// Handshake runs the client or server handshake -// protocol if it has not yet been run. -// -// Most uses of this package need not call Handshake explicitly: the -// first Read or Write will call it automatically. -// -// For control over canceling or setting a timeout on a handshake, use -// HandshakeContext or the Dialer's DialContext method instead. -func (c *Conn) Handshake() error { - return c.HandshakeContext(context.Background()) -} - -// HandshakeContext runs the client or server handshake -// protocol if it has not yet been run. -// -// The provided Context must be non-nil. If the context is canceled before -// the handshake is complete, the handshake is interrupted and an error is returned. -// Once the handshake has completed, cancellation of the context will not affect the -// connection. -// -// Most uses of this package need not call HandshakeContext explicitly: the -// first Read or Write will call it automatically. -func (c *Conn) HandshakeContext(ctx context.Context) error { - // Delegate to unexported method for named return - // without confusing documented signature. - return c.handshakeContext(ctx) -} - -func (c *Conn) handshakeContext(ctx context.Context) (ret error) { - // Fast sync/atomic-based exit if there is no handshake in flight and the - // last one succeeded without an error. Avoids the expensive context setup - // and mutex for most Read and Write calls. - if c.handshakeComplete() { - return nil - } - - handshakeCtx, cancel := context.WithCancel(ctx) - // Note: defer this before starting the "interrupter" goroutine - // so that we can tell the difference between the input being canceled and - // this cancellation. In the former case, we need to close the connection. - defer cancel() - - // Start the "interrupter" goroutine, if this context might be canceled. - // (The background context cannot). - // - // The interrupter goroutine waits for the input context to be done and - // closes the connection if this happens before the function returns. - if ctx.Done() != nil { - done := make(chan struct{}) - interruptRes := make(chan error, 1) - defer func() { - close(done) - if ctxErr := <-interruptRes; ctxErr != nil { - // Return context error to user. - ret = ctxErr - } - }() - go func() { - select { - case <-handshakeCtx.Done(): - // Close the connection, discarding the error - _ = c.conn.Close() - interruptRes <- handshakeCtx.Err() - case <-done: - interruptRes <- nil - } - }() - } - - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - if err := c.handshakeErr; err != nil { - return err - } - if c.handshakeComplete() { - return nil - } - - c.in.Lock() - defer c.in.Unlock() - - c.handshakeErr = c.handshakeFn(handshakeCtx) - if c.handshakeErr == nil { - c.handshakes++ - } else { - // If an error occurred during the handshake try to flush the - // alert that might be left in the buffer. - c.flush() - } - - if c.handshakeErr == nil && !c.handshakeComplete() { - c.handshakeErr = errors.New("tls: internal error: handshake should have had a result") - } - if c.handshakeErr != nil && c.handshakeComplete() { - panic("tls: internal error: handshake returned an error but is marked successful") - } - - return c.handshakeErr -} - -// ConnectionState returns basic TLS details about the connection. -func (c *Conn) ConnectionState() ConnectionState { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - return c.connectionStateLocked() -} - -// ConnectionStateWith0RTT returns basic TLS details (incl. 0-RTT status) about the connection. -func (c *Conn) ConnectionStateWith0RTT() ConnectionStateWith0RTT { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - return ConnectionStateWith0RTT{ - ConnectionState: c.connectionStateLocked(), - Used0RTT: c.used0RTT, - } -} - -func (c *Conn) connectionStateLocked() ConnectionState { - var state connectionState - state.HandshakeComplete = c.handshakeComplete() - state.Version = c.vers - state.NegotiatedProtocol = c.clientProtocol - state.DidResume = c.didResume - state.NegotiatedProtocolIsMutual = true - state.ServerName = c.serverName - state.CipherSuite = c.cipherSuite - state.PeerCertificates = c.peerCertificates - state.VerifiedChains = c.verifiedChains - state.SignedCertificateTimestamps = c.scts - state.OCSPResponse = c.ocspResponse - if !c.didResume && c.vers != VersionTLS13 { - if c.clientFinishedIsFirst { - state.TLSUnique = c.clientFinished[:] - } else { - state.TLSUnique = c.serverFinished[:] - } - } - if c.config.Renegotiation != RenegotiateNever { - state.ekm = noExportedKeyingMaterial - } else { - state.ekm = c.ekm - } - return toConnectionState(state) -} - -// OCSPResponse returns the stapled OCSP response from the TLS server, if -// any. (Only valid for client connections.) -func (c *Conn) OCSPResponse() []byte { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - return c.ocspResponse -} - -// VerifyHostname checks that the peer certificate chain is valid for -// connecting to host. If so, it returns nil; if not, it returns an error -// describing the problem. -func (c *Conn) VerifyHostname(host string) error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if !c.isClient { - return errors.New("tls: VerifyHostname called on TLS server connection") - } - if !c.handshakeComplete() { - return errors.New("tls: handshake has not yet been performed") - } - if len(c.verifiedChains) == 0 { - return errors.New("tls: handshake did not verify certificate chain") - } - return c.peerCertificates[0].VerifyHostname(host) -} - -func (c *Conn) handshakeComplete() bool { - return atomic.LoadUint32(&c.handshakeStatus) == 1 -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/cpu.go b/vendor/github.com/marten-seemann/qtls-go1-17/cpu.go deleted file mode 100644 index 121945087..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/cpu.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build !js -// +build !js - -package qtls - -import ( - "runtime" - - "golang.org/x/sys/cpu" -) - -var ( - hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ - hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL - // Keep in sync with crypto/aes/cipher_s390x.go. - hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && - (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM) - - hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 || - runtime.GOARCH == "arm64" && hasGCMAsmARM64 || - runtime.GOARCH == "s390x" && hasGCMAsmS390X -) diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/cpu_other.go b/vendor/github.com/marten-seemann/qtls-go1-17/cpu_other.go deleted file mode 100644 index 33f7d2194..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/cpu_other.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build js -// +build js - -package qtls - -var ( - hasGCMAsmAMD64 = false - hasGCMAsmARM64 = false - hasGCMAsmS390X = false - - hasAESGCMHardwareSupport = false -) diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_client.go b/vendor/github.com/marten-seemann/qtls-go1-17/handshake_client.go deleted file mode 100644 index ac5d0b4c2..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_client.go +++ /dev/null @@ -1,1111 +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 qtls - -import ( - "bytes" - "context" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "errors" - "fmt" - "hash" - "io" - "net" - "strings" - "sync/atomic" - "time" - - "golang.org/x/crypto/cryptobyte" -) - -const clientSessionStateVersion = 1 - -type clientHandshakeState struct { - c *Conn - ctx context.Context - serverHello *serverHelloMsg - hello *clientHelloMsg - suite *cipherSuite - finishedHash finishedHash - masterSecret []byte - session *clientSessionState -} - -func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) { - config := c.config - if len(config.ServerName) == 0 && !config.InsecureSkipVerify { - return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config") - } - - nextProtosLength := 0 - for _, proto := range config.NextProtos { - if l := len(proto); l == 0 || l > 255 { - return nil, nil, errors.New("tls: invalid NextProtos value") - } else { - nextProtosLength += 1 + l - } - } - if nextProtosLength > 0xffff { - return nil, nil, errors.New("tls: NextProtos values too large") - } - - var supportedVersions []uint16 - var clientHelloVersion uint16 - if c.extraConfig.usesAlternativeRecordLayer() { - if config.maxSupportedVersion() < VersionTLS13 { - return nil, nil, errors.New("tls: MaxVersion prevents QUIC from using TLS 1.3") - } - // Only offer TLS 1.3 when QUIC is used. - supportedVersions = []uint16{VersionTLS13} - clientHelloVersion = VersionTLS13 - } else { - supportedVersions = config.supportedVersions() - if len(supportedVersions) == 0 { - return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion") - } - clientHelloVersion = config.maxSupportedVersion() - } - - // The version at the beginning of the ClientHello was capped at TLS 1.2 - // for compatibility reasons. The supported_versions extension is used - // to negotiate versions now. See RFC 8446, Section 4.2.1. - if clientHelloVersion > VersionTLS12 { - clientHelloVersion = VersionTLS12 - } - - hello := &clientHelloMsg{ - vers: clientHelloVersion, - compressionMethods: []uint8{compressionNone}, - random: make([]byte, 32), - ocspStapling: true, - scts: true, - serverName: hostnameInSNI(config.ServerName), - supportedCurves: config.curvePreferences(), - supportedPoints: []uint8{pointFormatUncompressed}, - secureRenegotiationSupported: true, - alpnProtocols: config.NextProtos, - supportedVersions: supportedVersions, - } - - if c.handshakes > 0 { - hello.secureRenegotiation = c.clientFinished[:] - } - - preferenceOrder := cipherSuitesPreferenceOrder - if !hasAESGCMHardwareSupport { - preferenceOrder = cipherSuitesPreferenceOrderNoAES - } - configCipherSuites := config.cipherSuites() - hello.cipherSuites = make([]uint16, 0, len(configCipherSuites)) - - for _, suiteId := range preferenceOrder { - suite := mutualCipherSuite(configCipherSuites, suiteId) - if suite == nil { - continue - } - // Don't advertise TLS 1.2-only cipher suites unless - // we're attempting TLS 1.2. - if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { - continue - } - hello.cipherSuites = append(hello.cipherSuites, suiteId) - } - - _, err := io.ReadFull(config.rand(), hello.random) - if err != nil { - return nil, nil, errors.New("tls: short read from Rand: " + err.Error()) - } - - // A random session ID is used to detect when the server accepted a ticket - // and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as - // a compatibility measure (see RFC 8446, Section 4.1.2). - if c.extraConfig == nil || c.extraConfig.AlternativeRecordLayer == nil { - hello.sessionId = make([]byte, 32) - if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil { - return nil, nil, errors.New("tls: short read from Rand: " + err.Error()) - } - } - - if hello.vers >= VersionTLS12 { - hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms - } - - var params ecdheParameters - if hello.supportedVersions[0] == VersionTLS13 { - var suites []uint16 - for _, suiteID := range configCipherSuites { - for _, suite := range cipherSuitesTLS13 { - if suite.id == suiteID { - suites = append(suites, suiteID) - } - } - } - if len(suites) > 0 { - hello.cipherSuites = suites - } else { - if hasAESGCMHardwareSupport { - hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...) - } else { - hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...) - } - } - - curveID := config.curvePreferences()[0] - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve") - } - params, err = generateECDHEParameters(config.rand(), curveID) - if err != nil { - return nil, nil, err - } - hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} - } - - if hello.supportedVersions[0] == VersionTLS13 && c.extraConfig != nil && c.extraConfig.GetExtensions != nil { - hello.additionalExtensions = c.extraConfig.GetExtensions(typeClientHello) - } - - return hello, params, nil -} - -func (c *Conn) clientHandshake(ctx context.Context) (err error) { - if c.config == nil { - c.config = fromConfig(defaultConfig()) - } - c.setAlternativeRecordLayer() - - // This may be a renegotiation handshake, in which case some fields - // need to be reset. - c.didResume = false - - hello, ecdheParams, err := c.makeClientHello() - if err != nil { - return err - } - c.serverName = hello.serverName - - cacheKey, session, earlySecret, binderKey := c.loadSession(hello) - if cacheKey != "" && session != nil { - var deletedTicket bool - if session.vers == VersionTLS13 && hello.earlyData && c.extraConfig != nil && c.extraConfig.Enable0RTT { - // don't reuse a session ticket that enabled 0-RTT - c.config.ClientSessionCache.Put(cacheKey, nil) - deletedTicket = true - - if suite := cipherSuiteTLS13ByID(session.cipherSuite); suite != nil { - h := suite.hash.New() - h.Write(hello.marshal()) - clientEarlySecret := suite.deriveSecret(earlySecret, "c e traffic", h) - c.out.exportKey(Encryption0RTT, suite, clientEarlySecret) - if err := c.config.writeKeyLog(keyLogLabelEarlyTraffic, hello.random, clientEarlySecret); err != nil { - c.sendAlert(alertInternalError) - return err - } - } - } - if !deletedTicket { - defer func() { - // If we got a handshake failure when resuming a session, throw away - // the session ticket. See RFC 5077, Section 3.2. - // - // RFC 8446 makes no mention of dropping tickets on failure, but it - // does require servers to abort on invalid binders, so we need to - // delete tickets to recover from a corrupted PSK. - if err != nil { - c.config.ClientSessionCache.Put(cacheKey, nil) - } - }() - } - } - - if _, err := c.writeRecord(recordTypeHandshake, hello.marshal()); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - serverHello, ok := msg.(*serverHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(serverHello, msg) - } - - if err := c.pickTLSVersion(serverHello); err != nil { - return err - } - - // If we are negotiating a protocol version that's lower than what we - // support, check for the server downgrade canaries. - // See RFC 8446, Section 4.1.3. - maxVers := c.config.maxSupportedVersion() - tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12 - tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11 - if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) || - maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox") - } - - if c.vers == VersionTLS13 { - hs := &clientHandshakeStateTLS13{ - c: c, - ctx: ctx, - serverHello: serverHello, - hello: hello, - ecdheParams: ecdheParams, - session: session, - earlySecret: earlySecret, - binderKey: binderKey, - } - - // In TLS 1.3, session tickets are delivered after the handshake. - return hs.handshake() - } - - hs := &clientHandshakeState{ - c: c, - ctx: ctx, - serverHello: serverHello, - hello: hello, - session: session, - } - - if err := hs.handshake(); err != nil { - return err - } - - // If we had a successful handshake and hs.session is different from - // the one already cached - cache a new one. - if cacheKey != "" && hs.session != nil && session != hs.session { - c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(hs.session)) - } - - return nil -} - -// extract the app data saved in the session.nonce, -// and set the session.nonce to the actual nonce value -func (c *Conn) decodeSessionState(session *clientSessionState) (uint32 /* max early data */, []byte /* app data */, bool /* ok */) { - s := cryptobyte.String(session.nonce) - var version uint16 - if !s.ReadUint16(&version) { - return 0, nil, false - } - if version != clientSessionStateVersion { - return 0, nil, false - } - var maxEarlyData uint32 - if !s.ReadUint32(&maxEarlyData) { - return 0, nil, false - } - var appData []byte - if !readUint16LengthPrefixed(&s, &appData) { - return 0, nil, false - } - var nonce []byte - if !readUint16LengthPrefixed(&s, &nonce) { - return 0, nil, false - } - session.nonce = nonce - return maxEarlyData, appData, true -} - -func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string, - session *clientSessionState, earlySecret, binderKey []byte) { - if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { - return "", nil, nil, nil - } - - hello.ticketSupported = true - - if hello.supportedVersions[0] == VersionTLS13 { - // Require DHE on resumption as it guarantees forward secrecy against - // compromise of the session ticket key. See RFC 8446, Section 4.2.9. - hello.pskModes = []uint8{pskModeDHE} - } - - // Session resumption is not allowed if renegotiating because - // renegotiation is primarily used to allow a client to send a client - // certificate, which would be skipped if session resumption occurred. - if c.handshakes != 0 { - return "", nil, nil, nil - } - - // Try to resume a previously negotiated TLS session, if available. - cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config) - sess, ok := c.config.ClientSessionCache.Get(cacheKey) - if !ok || sess == nil { - return cacheKey, nil, nil, nil - } - session = fromClientSessionState(sess) - - var appData []byte - var maxEarlyData uint32 - if session.vers == VersionTLS13 { - var ok bool - maxEarlyData, appData, ok = c.decodeSessionState(session) - if !ok { // delete it, if parsing failed - c.config.ClientSessionCache.Put(cacheKey, nil) - return cacheKey, nil, nil, nil - } - } - - // Check that version used for the previous session is still valid. - versOk := false - for _, v := range hello.supportedVersions { - if v == session.vers { - versOk = true - break - } - } - if !versOk { - return cacheKey, nil, nil, nil - } - - // Check that the cached server certificate is not expired, and that it's - // valid for the ServerName. This should be ensured by the cache key, but - // protect the application from a faulty ClientSessionCache implementation. - if !c.config.InsecureSkipVerify { - if len(session.verifiedChains) == 0 { - // The original connection had InsecureSkipVerify, while this doesn't. - return cacheKey, nil, nil, nil - } - serverCert := session.serverCertificates[0] - if c.config.time().After(serverCert.NotAfter) { - // Expired certificate, delete the entry. - c.config.ClientSessionCache.Put(cacheKey, nil) - return cacheKey, nil, nil, nil - } - if err := serverCert.VerifyHostname(c.config.ServerName); err != nil { - return cacheKey, nil, nil, nil - } - } - - if session.vers != VersionTLS13 { - // In TLS 1.2 the cipher suite must match the resumed session. Ensure we - // are still offering it. - if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil { - return cacheKey, nil, nil, nil - } - - hello.sessionTicket = session.sessionTicket - return - } - - // Check that the session ticket is not expired. - if c.config.time().After(session.useBy) { - c.config.ClientSessionCache.Put(cacheKey, nil) - return cacheKey, nil, nil, nil - } - - // In TLS 1.3 the KDF hash must match the resumed session. Ensure we - // offer at least one cipher suite with that hash. - cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite) - if cipherSuite == nil { - return cacheKey, nil, nil, nil - } - cipherSuiteOk := false - for _, offeredID := range hello.cipherSuites { - offeredSuite := cipherSuiteTLS13ByID(offeredID) - if offeredSuite != nil && offeredSuite.hash == cipherSuite.hash { - cipherSuiteOk = true - break - } - } - if !cipherSuiteOk { - return cacheKey, nil, nil, nil - } - - // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1. - ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond) - identity := pskIdentity{ - label: session.sessionTicket, - obfuscatedTicketAge: ticketAge + session.ageAdd, - } - hello.pskIdentities = []pskIdentity{identity} - hello.pskBinders = [][]byte{make([]byte, cipherSuite.hash.Size())} - - // Compute the PSK binders. See RFC 8446, Section 4.2.11.2. - psk := cipherSuite.expandLabel(session.masterSecret, "resumption", - session.nonce, cipherSuite.hash.Size()) - earlySecret = cipherSuite.extract(psk, nil) - binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil) - if c.extraConfig != nil { - hello.earlyData = c.extraConfig.Enable0RTT && maxEarlyData > 0 - } - transcript := cipherSuite.hash.New() - transcript.Write(hello.marshalWithoutBinders()) - pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)} - hello.updateBinders(pskBinders) - - if session.vers == VersionTLS13 && c.extraConfig != nil && c.extraConfig.SetAppDataFromSessionState != nil { - c.extraConfig.SetAppDataFromSessionState(appData) - } - return -} - -func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error { - peerVersion := serverHello.vers - if serverHello.supportedVersion != 0 { - peerVersion = serverHello.supportedVersion - } - - vers, ok := c.config.mutualVersion([]uint16{peerVersion}) - if !ok { - c.sendAlert(alertProtocolVersion) - return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion) - } - - c.vers = vers - c.haveVers = true - c.in.version = vers - c.out.version = vers - - return nil -} - -// Does the handshake, either a full one or resumes old session. Requires hs.c, -// hs.hello, hs.serverHello, and, optionally, hs.session to be set. -func (hs *clientHandshakeState) handshake() error { - c := hs.c - - isResume, err := hs.processServerHello() - if err != nil { - return err - } - - hs.finishedHash = newFinishedHash(c.vers, hs.suite) - - // No signatures of the handshake are needed in a resumption. - // Otherwise, in a full handshake, if we don't have any certificates - // configured then we will never send a CertificateVerify message and - // thus no signatures are needed in that case either. - if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) { - hs.finishedHash.discardHandshakeBuffer() - } - - hs.finishedHash.Write(hs.hello.marshal()) - hs.finishedHash.Write(hs.serverHello.marshal()) - - c.buffering = true - c.didResume = isResume - if isResume { - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.readSessionTicket(); err != nil { - return err - } - if err := hs.readFinished(c.serverFinished[:]); err != nil { - return err - } - c.clientFinishedIsFirst = false - // Make sure the connection is still being verified whether or not this - // is a resumption. Resumptions currently don't reverify certificates so - // they don't call verifyServerCertificate. See Issue 31641. - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - if err := hs.sendFinished(c.clientFinished[:]); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - } else { - if err := hs.doFullHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.sendFinished(c.clientFinished[:]); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - c.clientFinishedIsFirst = true - if err := hs.readSessionTicket(); err != nil { - return err - } - if err := hs.readFinished(c.serverFinished[:]); err != nil { - return err - } - } - - c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random) - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -func (hs *clientHandshakeState) pickCipherSuite() error { - if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil { - hs.c.sendAlert(alertHandshakeFailure) - return errors.New("tls: server chose an unconfigured cipher suite") - } - - hs.c.cipherSuite = hs.suite.id - return nil -} - -func (hs *clientHandshakeState) doFullHandshake() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - certMsg, ok := msg.(*certificateMsg) - if !ok || len(certMsg.certificates) == 0 { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - hs.finishedHash.Write(certMsg.marshal()) - - msg, err = c.readHandshake() - if err != nil { - return err - } - - cs, ok := msg.(*certificateStatusMsg) - if ok { - // RFC4366 on Certificate Status Request: - // The server MAY return a "certificate_status" message. - - if !hs.serverHello.ocspStapling { - // If a server returns a "CertificateStatus" message, then the - // server MUST have included an extension of type "status_request" - // with empty "extension_data" in the extended server hello. - - c.sendAlert(alertUnexpectedMessage) - return errors.New("tls: received unexpected CertificateStatus message") - } - hs.finishedHash.Write(cs.marshal()) - - c.ocspResponse = cs.response - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - if c.handshakes == 0 { - // If this is the first handshake on a connection, process and - // (optionally) verify the server's certificates. - if err := c.verifyServerCertificate(certMsg.certificates); err != nil { - return err - } - } else { - // This is a renegotiation handshake. We require that the - // server's identity (i.e. leaf certificate) is unchanged and - // thus any previous trust decision is still valid. - // - // See https://mitls.org/pages/attacks/3SHAKE for the - // motivation behind this requirement. - if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) { - c.sendAlert(alertBadCertificate) - return errors.New("tls: server's identity changed during renegotiation") - } - } - - keyAgreement := hs.suite.ka(c.vers) - - skx, ok := msg.(*serverKeyExchangeMsg) - if ok { - hs.finishedHash.Write(skx.marshal()) - err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx) - if err != nil { - c.sendAlert(alertUnexpectedMessage) - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - var chainToSend *Certificate - var certRequested bool - certReq, ok := msg.(*certificateRequestMsg) - if ok { - certRequested = true - hs.finishedHash.Write(certReq.marshal()) - - cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq) - if chainToSend, err = c.getClientCertificate(cri); err != nil { - c.sendAlert(alertInternalError) - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - shd, ok := msg.(*serverHelloDoneMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(shd, msg) - } - hs.finishedHash.Write(shd.marshal()) - - // If the server requested a certificate then we have to send a - // Certificate message, even if it's empty because we don't have a - // certificate to send. - if certRequested { - certMsg = new(certificateMsg) - certMsg.certificates = chainToSend.Certificate - hs.finishedHash.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - } - - preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0]) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - if ckx != nil { - hs.finishedHash.Write(ckx.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, ckx.marshal()); err != nil { - return err - } - } - - if chainToSend != nil && len(chainToSend.Certificate) > 0 { - certVerify := &certificateVerifyMsg{} - - key, ok := chainToSend.PrivateKey.(crypto.Signer) - if !ok { - c.sendAlert(alertInternalError) - return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey) - } - - var sigType uint8 - var sigHash crypto.Hash - if c.vers >= VersionTLS12 { - signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms) - if err != nil { - c.sendAlert(alertIllegalParameter) - return err - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - certVerify.hasSignatureAlgorithm = true - certVerify.signatureAlgorithm = signatureAlgorithm - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public()) - if err != nil { - c.sendAlert(alertIllegalParameter) - return err - } - } - - signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret) - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - hs.finishedHash.Write(certVerify.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certVerify.marshal()); err != nil { - return err - } - } - - hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random) - if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to write to key log: " + err.Error()) - } - - hs.finishedHash.discardHandshakeBuffer() - - return nil -} - -func (hs *clientHandshakeState) establishKeys() error { - c := hs.c - - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) - var clientCipher, serverCipher interface{} - var clientHash, serverHash hash.Hash - if hs.suite.cipher != nil { - clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */) - clientHash = hs.suite.mac(clientMAC) - serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */) - serverHash = hs.suite.mac(serverMAC) - } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) - } - - c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) - c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) - return nil -} - -func (hs *clientHandshakeState) serverResumedSession() bool { - // If the server responded with the same sessionId then it means the - // sessionTicket is being used to resume a TLS session. - return hs.session != nil && hs.hello.sessionId != nil && - bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId) -} - -func (hs *clientHandshakeState) processServerHello() (bool, error) { - c := hs.c - - if err := hs.pickCipherSuite(); err != nil { - return false, err - } - - if hs.serverHello.compressionMethod != compressionNone { - c.sendAlert(alertUnexpectedMessage) - return false, errors.New("tls: server selected unsupported compression format") - } - - if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported { - c.secureRenegotiation = true - if len(hs.serverHello.secureRenegotiation) != 0 { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: initial handshake had non-empty renegotiation extension") - } - } - - if c.handshakes > 0 && c.secureRenegotiation { - var expectedSecureRenegotiation [24]byte - copy(expectedSecureRenegotiation[:], c.clientFinished[:]) - copy(expectedSecureRenegotiation[12:], c.serverFinished[:]) - if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: incorrect renegotiation extension contents") - } - } - - if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol); err != nil { - c.sendAlert(alertUnsupportedExtension) - return false, err - } - c.clientProtocol = hs.serverHello.alpnProtocol - - c.scts = hs.serverHello.scts - - if !hs.serverResumedSession() { - return false, nil - } - - if hs.session.vers != c.vers { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: server resumed a session with a different version") - } - - if hs.session.cipherSuite != hs.suite.id { - c.sendAlert(alertHandshakeFailure) - return false, errors.New("tls: server resumed a session with a different cipher suite") - } - - // Restore masterSecret, peerCerts, and ocspResponse from previous state - hs.masterSecret = hs.session.masterSecret - c.peerCertificates = hs.session.serverCertificates - c.verifiedChains = hs.session.verifiedChains - c.ocspResponse = hs.session.ocspResponse - // Let the ServerHello SCTs override the session SCTs from the original - // connection, if any are provided - if len(c.scts) == 0 && len(hs.session.scts) != 0 { - c.scts = hs.session.scts - } - - return true, nil -} - -// checkALPN ensure that the server's choice of ALPN protocol is compatible with -// the protocols that we advertised in the Client Hello. -func checkALPN(clientProtos []string, serverProto string) error { - if serverProto == "" { - return nil - } - if len(clientProtos) == 0 { - return errors.New("tls: server advertised unrequested ALPN extension") - } - for _, proto := range clientProtos { - if proto == serverProto { - return nil - } - } - return errors.New("tls: server selected unadvertised ALPN protocol") -} - -func (hs *clientHandshakeState) readFinished(out []byte) error { - c := hs.c - - if err := c.readChangeCipherSpec(); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - serverFinished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(serverFinished, msg) - } - - verify := hs.finishedHash.serverSum(hs.masterSecret) - if len(verify) != len(serverFinished.verifyData) || - subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: server's Finished message was incorrect") - } - hs.finishedHash.Write(serverFinished.marshal()) - copy(out, verify) - return nil -} - -func (hs *clientHandshakeState) readSessionTicket() error { - if !hs.serverHello.ticketSupported { - return nil - } - - c := hs.c - msg, err := c.readHandshake() - if err != nil { - return err - } - sessionTicketMsg, ok := msg.(*newSessionTicketMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(sessionTicketMsg, msg) - } - hs.finishedHash.Write(sessionTicketMsg.marshal()) - - hs.session = &clientSessionState{ - sessionTicket: sessionTicketMsg.ticket, - vers: c.vers, - cipherSuite: hs.suite.id, - masterSecret: hs.masterSecret, - serverCertificates: c.peerCertificates, - verifiedChains: c.verifiedChains, - receivedAt: c.config.time(), - ocspResponse: c.ocspResponse, - scts: c.scts, - } - - return nil -} - -func (hs *clientHandshakeState) sendFinished(out []byte) error { - c := hs.c - - if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { - return err - } - - finished := new(finishedMsg) - finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret) - hs.finishedHash.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - copy(out, finished.verifyData) - return nil -} - -// verifyServerCertificate parses and verifies the provided chain, setting -// c.verifiedChains and c.peerCertificates or sending the appropriate alert. -func (c *Conn) verifyServerCertificate(certificates [][]byte) error { - certs := make([]*x509.Certificate, len(certificates)) - for i, asn1Data := range certificates { - cert, err := x509.ParseCertificate(asn1Data) - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to parse certificate from server: " + err.Error()) - } - certs[i] = cert - } - - if !c.config.InsecureSkipVerify { - opts := x509.VerifyOptions{ - Roots: c.config.RootCAs, - CurrentTime: c.config.time(), - DNSName: c.config.ServerName, - Intermediates: x509.NewCertPool(), - } - for _, cert := range certs[1:] { - opts.Intermediates.AddCert(cert) - } - var err error - c.verifiedChains, err = certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - switch certs[0].PublicKey.(type) { - case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey: - break - default: - c.sendAlert(alertUnsupportedCertificate) - return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey) - } - - c.peerCertificates = certs - - if c.config.VerifyPeerCertificate != nil { - if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - return nil -} - -// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS -// <= 1.2 CertificateRequest, making an effort to fill in missing information. -func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo { - cri := &certificateRequestInfo{ - AcceptableCAs: certReq.certificateAuthorities, - Version: vers, - ctx: ctx, - } - - var rsaAvail, ecAvail bool - for _, certType := range certReq.certificateTypes { - switch certType { - case certTypeRSASign: - rsaAvail = true - case certTypeECDSASign: - ecAvail = true - } - } - - if !certReq.hasSignatureAlgorithm { - // Prior to TLS 1.2, signature schemes did not exist. In this case we - // make up a list based on the acceptable certificate types, to help - // GetClientCertificate and SupportsCertificate select the right certificate. - // The hash part of the SignatureScheme is a lie here, because - // TLS 1.0 and 1.1 always use MD5+SHA1 for RSA and SHA1 for ECDSA. - switch { - case rsaAvail && ecAvail: - cri.SignatureSchemes = []SignatureScheme{ - ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, - PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1, - } - case rsaAvail: - cri.SignatureSchemes = []SignatureScheme{ - PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1, - } - case ecAvail: - cri.SignatureSchemes = []SignatureScheme{ - ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, - } - } - return toCertificateRequestInfo(cri) - } - - // Filter the signature schemes based on the certificate types. - // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated"). - cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms)) - for _, sigScheme := range certReq.supportedSignatureAlgorithms { - sigType, _, err := typeAndHashFromSignatureScheme(sigScheme) - if err != nil { - continue - } - switch sigType { - case signatureECDSA, signatureEd25519: - if ecAvail { - cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme) - } - case signatureRSAPSS, signaturePKCS1v15: - if rsaAvail { - cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme) - } - } - } - - return toCertificateRequestInfo(cri) -} - -func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) { - if c.config.GetClientCertificate != nil { - return c.config.GetClientCertificate(cri) - } - - for _, chain := range c.config.Certificates { - if err := cri.SupportsCertificate(&chain); err != nil { - continue - } - return &chain, nil - } - - // No acceptable certificate found. Don't send a certificate. - return new(Certificate), nil -} - -const clientSessionCacheKeyPrefix = "qtls-" - -// clientSessionCacheKey returns a key used to cache sessionTickets that could -// be used to resume previously negotiated TLS sessions with a server. -func clientSessionCacheKey(serverAddr net.Addr, config *config) string { - if len(config.ServerName) > 0 { - return clientSessionCacheKeyPrefix + config.ServerName - } - return clientSessionCacheKeyPrefix + serverAddr.String() -} - -// hostnameInSNI converts name into an appropriate hostname for SNI. -// Literal IP addresses and absolute FQDNs are not permitted as SNI values. -// See RFC 6066, Section 3. -func hostnameInSNI(name string) string { - host := name - if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' { - host = host[1 : len(host)-1] - } - if i := strings.LastIndex(host, "%"); i > 0 { - host = host[:i] - } - if net.ParseIP(host) != nil { - return "" - } - for len(name) > 0 && name[len(name)-1] == '.' { - name = name[:len(name)-1] - } - return name -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_client_tls13.go b/vendor/github.com/marten-seemann/qtls-go1-17/handshake_client_tls13.go deleted file mode 100644 index 0de59fc1e..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_client_tls13.go +++ /dev/null @@ -1,732 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "bytes" - "context" - "crypto" - "crypto/hmac" - "crypto/rsa" - "encoding/binary" - "errors" - "hash" - "sync/atomic" - "time" - - "golang.org/x/crypto/cryptobyte" -) - -type clientHandshakeStateTLS13 struct { - c *Conn - ctx context.Context - serverHello *serverHelloMsg - hello *clientHelloMsg - ecdheParams ecdheParameters - - session *clientSessionState - earlySecret []byte - binderKey []byte - - certReq *certificateRequestMsgTLS13 - usingPSK bool - sentDummyCCS bool - suite *cipherSuiteTLS13 - transcript hash.Hash - masterSecret []byte - trafficSecret []byte // client_application_traffic_secret_0 -} - -// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheParams, and, -// optionally, hs.session, hs.earlySecret and hs.binderKey to be set. -func (hs *clientHandshakeStateTLS13) handshake() error { - c := hs.c - - // The server must not select TLS 1.3 in a renegotiation. See RFC 8446, - // sections 4.1.2 and 4.1.3. - if c.handshakes > 0 { - c.sendAlert(alertProtocolVersion) - return errors.New("tls: server selected TLS 1.3 in a renegotiation") - } - - // Consistency check on the presence of a keyShare and its parameters. - if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 { - return c.sendAlert(alertInternalError) - } - - if err := hs.checkServerHelloOrHRR(); err != nil { - return err - } - - hs.transcript = hs.suite.hash.New() - hs.transcript.Write(hs.hello.marshal()) - - if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - if err := hs.processHelloRetryRequest(); err != nil { - return err - } - } - - hs.transcript.Write(hs.serverHello.marshal()) - - c.buffering = true - if err := hs.processServerHello(); err != nil { - return err - } - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - if err := hs.establishHandshakeKeys(); err != nil { - return err - } - if err := hs.readServerParameters(); err != nil { - return err - } - if err := hs.readServerCertificate(); err != nil { - return err - } - if err := hs.readServerFinished(); err != nil { - return err - } - if err := hs.sendClientCertificate(); err != nil { - return err - } - if err := hs.sendClientFinished(); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -// checkServerHelloOrHRR does validity checks that apply to both ServerHello and -// HelloRetryRequest messages. It sets hs.suite. -func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error { - c := hs.c - - if hs.serverHello.supportedVersion == 0 { - c.sendAlert(alertMissingExtension) - return errors.New("tls: server selected TLS 1.3 using the legacy version field") - } - - if hs.serverHello.supportedVersion != VersionTLS13 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected an invalid version after a HelloRetryRequest") - } - - if hs.serverHello.vers != VersionTLS12 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server sent an incorrect legacy version") - } - - if hs.serverHello.ocspStapling || - hs.serverHello.ticketSupported || - hs.serverHello.secureRenegotiationSupported || - len(hs.serverHello.secureRenegotiation) != 0 || - len(hs.serverHello.alpnProtocol) != 0 || - len(hs.serverHello.scts) != 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3") - } - - if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server did not echo the legacy session ID") - } - - if hs.serverHello.compressionMethod != compressionNone { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected unsupported compression format") - } - - selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite) - if hs.suite != nil && selectedSuite != hs.suite { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server changed cipher suite after a HelloRetryRequest") - } - if selectedSuite == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server chose an unconfigured cipher suite") - } - hs.suite = selectedSuite - c.cipherSuite = hs.suite.id - - return nil -} - -// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility -// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. -func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error { - if hs.sentDummyCCS { - return nil - } - hs.sentDummyCCS = true - - _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - return err -} - -// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and -// resends hs.hello, and reads the new ServerHello into hs.serverHello. -func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error { - c := hs.c - - // The first ClientHello gets double-hashed into the transcript upon a - // HelloRetryRequest. (The idea is that the server might offload transcript - // storage to the client in the cookie.) See RFC 8446, Section 4.4.1. - chHash := hs.transcript.Sum(nil) - hs.transcript.Reset() - hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) - hs.transcript.Write(chHash) - hs.transcript.Write(hs.serverHello.marshal()) - - // The only HelloRetryRequest extensions we support are key_share and - // cookie, and clients must abort the handshake if the HRR would not result - // in any change in the ClientHello. - if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server sent an unnecessary HelloRetryRequest message") - } - - if hs.serverHello.cookie != nil { - hs.hello.cookie = hs.serverHello.cookie - } - - if hs.serverHello.serverShare.group != 0 { - c.sendAlert(alertDecodeError) - return errors.New("tls: received malformed key_share extension") - } - - // If the server sent a key_share extension selecting a group, ensure it's - // a group we advertised but did not send a key share for, and send a key - // share for it this time. - if curveID := hs.serverHello.selectedGroup; curveID != 0 { - curveOK := false - for _, id := range hs.hello.supportedCurves { - if id == curveID { - curveOK = true - break - } - } - if !curveOK { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected unsupported group") - } - if hs.ecdheParams.CurveID() == curveID { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share") - } - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - c.sendAlert(alertInternalError) - return errors.New("tls: CurvePreferences includes unsupported curve") - } - params, err := generateECDHEParameters(c.config.rand(), curveID) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - hs.ecdheParams = params - hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}} - } - - hs.hello.raw = nil - if len(hs.hello.pskIdentities) > 0 { - pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) - if pskSuite == nil { - return c.sendAlert(alertInternalError) - } - if pskSuite.hash == hs.suite.hash { - // Update binders and obfuscated_ticket_age. - ticketAge := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond) - hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + hs.session.ageAdd - - transcript := hs.suite.hash.New() - transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) - transcript.Write(chHash) - transcript.Write(hs.serverHello.marshal()) - transcript.Write(hs.hello.marshalWithoutBinders()) - pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)} - hs.hello.updateBinders(pskBinders) - } else { - // Server selected a cipher suite incompatible with the PSK. - hs.hello.pskIdentities = nil - hs.hello.pskBinders = nil - } - } - - if hs.hello.earlyData && c.extraConfig != nil && c.extraConfig.Rejected0RTT != nil { - c.extraConfig.Rejected0RTT() - } - hs.hello.earlyData = false // disable 0-RTT - - hs.transcript.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - serverHello, ok := msg.(*serverHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(serverHello, msg) - } - hs.serverHello = serverHello - - if err := hs.checkServerHelloOrHRR(); err != nil { - return err - } - - return nil -} - -func (hs *clientHandshakeStateTLS13) processServerHello() error { - c := hs.c - - if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) { - c.sendAlert(alertUnexpectedMessage) - return errors.New("tls: server sent two HelloRetryRequest messages") - } - - if len(hs.serverHello.cookie) != 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: server sent a cookie in a normal ServerHello") - } - - if hs.serverHello.selectedGroup != 0 { - c.sendAlert(alertDecodeError) - return errors.New("tls: malformed key_share extension") - } - - if hs.serverHello.serverShare.group == 0 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server did not send a key share") - } - if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected unsupported group") - } - - if !hs.serverHello.selectedIdentityPresent { - return nil - } - - if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected an invalid PSK") - } - - if len(hs.hello.pskIdentities) != 1 || hs.session == nil { - return c.sendAlert(alertInternalError) - } - pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite) - if pskSuite == nil { - return c.sendAlert(alertInternalError) - } - if pskSuite.hash != hs.suite.hash { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: server selected an invalid PSK and cipher suite pair") - } - - hs.usingPSK = true - c.didResume = true - c.peerCertificates = hs.session.serverCertificates - c.verifiedChains = hs.session.verifiedChains - c.ocspResponse = hs.session.ocspResponse - c.scts = hs.session.scts - return nil -} - -func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error { - c := hs.c - - sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data) - if sharedKey == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid server key share") - } - - earlySecret := hs.earlySecret - if !hs.usingPSK { - earlySecret = hs.suite.extract(nil, nil) - } - handshakeSecret := hs.suite.extract(sharedKey, - hs.suite.deriveSecret(earlySecret, "derived", nil)) - - clientSecret := hs.suite.deriveSecret(handshakeSecret, - clientHandshakeTrafficLabel, hs.transcript) - c.out.exportKey(EncryptionHandshake, hs.suite, clientSecret) - c.out.setTrafficSecret(hs.suite, clientSecret) - serverSecret := hs.suite.deriveSecret(handshakeSecret, - serverHandshakeTrafficLabel, hs.transcript) - c.in.exportKey(EncryptionHandshake, hs.suite, serverSecret) - c.in.setTrafficSecret(hs.suite, serverSecret) - - err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - hs.masterSecret = hs.suite.extract(nil, - hs.suite.deriveSecret(handshakeSecret, "derived", nil)) - - return nil -} - -func (hs *clientHandshakeStateTLS13) readServerParameters() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - - encryptedExtensions, ok := msg.(*encryptedExtensionsMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(encryptedExtensions, msg) - } - // Notify the caller if 0-RTT was rejected. - if !encryptedExtensions.earlyData && hs.hello.earlyData && c.extraConfig != nil && c.extraConfig.Rejected0RTT != nil { - c.extraConfig.Rejected0RTT() - } - c.used0RTT = encryptedExtensions.earlyData - if hs.c.extraConfig != nil && hs.c.extraConfig.ReceivedExtensions != nil { - hs.c.extraConfig.ReceivedExtensions(typeEncryptedExtensions, encryptedExtensions.additionalExtensions) - } - hs.transcript.Write(encryptedExtensions.marshal()) - - if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol); err != nil { - c.sendAlert(alertUnsupportedExtension) - return err - } - c.clientProtocol = encryptedExtensions.alpnProtocol - - if c.extraConfig != nil && c.extraConfig.EnforceNextProtoSelection { - if len(encryptedExtensions.alpnProtocol) == 0 { - // the server didn't select an ALPN - c.sendAlert(alertNoApplicationProtocol) - return errors.New("ALPN negotiation failed. Server didn't offer any protocols") - } - } - return nil -} - -func (hs *clientHandshakeStateTLS13) readServerCertificate() error { - c := hs.c - - // Either a PSK or a certificate is always used, but not both. - // See RFC 8446, Section 4.1.1. - if hs.usingPSK { - // Make sure the connection is still being verified whether or not this - // is a resumption. Resumptions currently don't reverify certificates so - // they don't call verifyServerCertificate. See Issue 31641. - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - return nil - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - certReq, ok := msg.(*certificateRequestMsgTLS13) - if ok { - hs.transcript.Write(certReq.marshal()) - - hs.certReq = certReq - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - certMsg, ok := msg.(*certificateMsgTLS13) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - if len(certMsg.certificate.Certificate) == 0 { - c.sendAlert(alertDecodeError) - return errors.New("tls: received empty certificates message") - } - hs.transcript.Write(certMsg.marshal()) - - c.scts = certMsg.certificate.SignedCertificateTimestamps - c.ocspResponse = certMsg.certificate.OCSPStaple - - if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil { - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certVerify, msg) - } - - // See RFC 8446, Section 4.4.3. - if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: certificate used with invalid signature algorithm") - } - sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: certificate used with invalid signature algorithm") - } - signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) - if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, - sigHash, signed, certVerify.signature); err != nil { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid signature by the server certificate: " + err.Error()) - } - - hs.transcript.Write(certVerify.marshal()) - - return nil -} - -func (hs *clientHandshakeStateTLS13) readServerFinished() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - - finished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(finished, msg) - } - - expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) - if !hmac.Equal(expectedMAC, finished.verifyData) { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid server finished hash") - } - - hs.transcript.Write(finished.marshal()) - - // Derive secrets that take context through the server Finished. - - hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, - clientApplicationTrafficLabel, hs.transcript) - serverSecret := hs.suite.deriveSecret(hs.masterSecret, - serverApplicationTrafficLabel, hs.transcript) - c.in.exportKey(EncryptionApplication, hs.suite, serverSecret) - c.in.setTrafficSecret(hs.suite, serverSecret) - - err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) - - return nil -} - -func (hs *clientHandshakeStateTLS13) sendClientCertificate() error { - c := hs.c - - if hs.certReq == nil { - return nil - } - - cert, err := c.getClientCertificate(toCertificateRequestInfo(&certificateRequestInfo{ - AcceptableCAs: hs.certReq.certificateAuthorities, - SignatureSchemes: hs.certReq.supportedSignatureAlgorithms, - Version: c.vers, - ctx: hs.ctx, - })) - if err != nil { - return err - } - - certMsg := new(certificateMsgTLS13) - - certMsg.certificate = *cert - certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0 - certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0 - - hs.transcript.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - - // If we sent an empty certificate message, skip the CertificateVerify. - if len(cert.Certificate) == 0 { - return nil - } - - certVerifyMsg := new(certificateVerifyMsg) - certVerifyMsg.hasSignatureAlgorithm = true - - certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms) - if err != nil { - // getClientCertificate returned a certificate incompatible with the - // CertificateRequestInfo supported signature algorithms. - c.sendAlert(alertHandshakeFailure) - return err - } - - sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - - signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) - if err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to sign handshake: " + err.Error()) - } - certVerifyMsg.signature = sig - - hs.transcript.Write(certVerifyMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *clientHandshakeStateTLS13) sendClientFinished() error { - c := hs.c - - finished := &finishedMsg{ - verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), - } - - hs.transcript.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - - c.out.exportKey(EncryptionApplication, hs.suite, hs.trafficSecret) - c.out.setTrafficSecret(hs.suite, hs.trafficSecret) - - if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil { - c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, - resumptionLabel, hs.transcript) - } - - return nil -} - -func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error { - if !c.isClient { - c.sendAlert(alertUnexpectedMessage) - return errors.New("tls: received new session ticket from a client") - } - - if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil { - return nil - } - - // See RFC 8446, Section 4.6.1. - if msg.lifetime == 0 { - return nil - } - lifetime := time.Duration(msg.lifetime) * time.Second - if lifetime > maxSessionTicketLifetime { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: received a session ticket with invalid lifetime") - } - - cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite) - if cipherSuite == nil || c.resumptionSecret == nil { - return c.sendAlert(alertInternalError) - } - - // We need to save the max_early_data_size that the server sent us, in order - // to decide if we're going to try 0-RTT with this ticket. - // However, at the same time, the qtls.ClientSessionTicket needs to be equal to - // the tls.ClientSessionTicket, so we can't just add a new field to the struct. - // We therefore abuse the nonce field (which is a byte slice) - nonceWithEarlyData := make([]byte, len(msg.nonce)+4) - binary.BigEndian.PutUint32(nonceWithEarlyData, msg.maxEarlyData) - copy(nonceWithEarlyData[4:], msg.nonce) - - var appData []byte - if c.extraConfig != nil && c.extraConfig.GetAppDataForSessionState != nil { - appData = c.extraConfig.GetAppDataForSessionState() - } - var b cryptobyte.Builder - b.AddUint16(clientSessionStateVersion) // revision - b.AddUint32(msg.maxEarlyData) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(appData) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(msg.nonce) - }) - - // Save the resumption_master_secret and nonce instead of deriving the PSK - // to do the least amount of work on NewSessionTicket messages before we - // know if the ticket will be used. Forward secrecy of resumed connections - // is guaranteed by the requirement for pskModeDHE. - session := &clientSessionState{ - sessionTicket: msg.label, - vers: c.vers, - cipherSuite: c.cipherSuite, - masterSecret: c.resumptionSecret, - serverCertificates: c.peerCertificates, - verifiedChains: c.verifiedChains, - receivedAt: c.config.time(), - nonce: b.BytesOrPanic(), - useBy: c.config.time().Add(lifetime), - ageAdd: msg.ageAdd, - ocspResponse: c.ocspResponse, - scts: c.scts, - } - - cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config) - c.config.ClientSessionCache.Put(cacheKey, toClientSessionState(session)) - - return nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_messages.go b/vendor/github.com/marten-seemann/qtls-go1-17/handshake_messages.go deleted file mode 100644 index 1ab757626..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_messages.go +++ /dev/null @@ -1,1832 +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 qtls - -import ( - "fmt" - "strings" - - "golang.org/x/crypto/cryptobyte" -) - -// The marshalingFunction type is an adapter to allow the use of ordinary -// functions as cryptobyte.MarshalingValue. -type marshalingFunction func(b *cryptobyte.Builder) error - -func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error { - return f(b) -} - -// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If -// the length of the sequence is not the value specified, it produces an error. -func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) { - b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error { - if len(v) != n { - return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v)) - } - b.AddBytes(v) - return nil - })) -} - -// addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder. -func addUint64(b *cryptobyte.Builder, v uint64) { - b.AddUint32(uint32(v >> 32)) - b.AddUint32(uint32(v)) -} - -// readUint64 decodes a big-endian, 64-bit value into out and advances over it. -// It reports whether the read was successful. -func readUint64(s *cryptobyte.String, out *uint64) bool { - var hi, lo uint32 - if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) { - return false - } - *out = uint64(hi)<<32 | uint64(lo) - return true -} - -// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a -// []byte instead of a cryptobyte.String. -func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { - return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out)) -} - -// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a -// []byte instead of a cryptobyte.String. -func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { - return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out)) -} - -// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a -// []byte instead of a cryptobyte.String. -func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool { - return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out)) -} - -type clientHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuites []uint16 - compressionMethods []uint8 - serverName string - ocspStapling bool - supportedCurves []CurveID - supportedPoints []uint8 - ticketSupported bool - sessionTicket []uint8 - supportedSignatureAlgorithms []SignatureScheme - supportedSignatureAlgorithmsCert []SignatureScheme - secureRenegotiationSupported bool - secureRenegotiation []byte - alpnProtocols []string - scts bool - supportedVersions []uint16 - cookie []byte - keyShares []keyShare - earlyData bool - pskModes []uint8 - pskIdentities []pskIdentity - pskBinders [][]byte - additionalExtensions []Extension -} - -func (m *clientHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeClientHello) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.vers) - addBytesWithLength(b, m.random, 32) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.sessionId) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, suite := range m.cipherSuites { - b.AddUint16(suite) - } - }) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.compressionMethods) - }) - - // If extensions aren't present, omit them. - var extensionsPresent bool - bWithoutExtensions := *b - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if len(m.serverName) > 0 { - // RFC 6066, Section 3 - b.AddUint16(extensionServerName) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(0) // name_type = host_name - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.serverName)) - }) - }) - }) - } - if m.ocspStapling { - // RFC 4366, Section 3.6 - b.AddUint16(extensionStatusRequest) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(1) // status_type = ocsp - b.AddUint16(0) // empty responder_id_list - b.AddUint16(0) // empty request_extensions - }) - } - if len(m.supportedCurves) > 0 { - // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 - b.AddUint16(extensionSupportedCurves) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, curve := range m.supportedCurves { - b.AddUint16(uint16(curve)) - } - }) - }) - } - if len(m.supportedPoints) > 0 { - // RFC 4492, Section 5.1.2 - b.AddUint16(extensionSupportedPoints) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.supportedPoints) - }) - }) - } - if m.ticketSupported { - // RFC 5077, Section 3.2 - b.AddUint16(extensionSessionTicket) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.sessionTicket) - }) - } - if len(m.supportedSignatureAlgorithms) > 0 { - // RFC 5246, Section 7.4.1.4.1 - b.AddUint16(extensionSignatureAlgorithms) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithms { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if len(m.supportedSignatureAlgorithmsCert) > 0 { - // RFC 8446, Section 4.2.3 - b.AddUint16(extensionSignatureAlgorithmsCert) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if m.secureRenegotiationSupported { - // RFC 5746, Section 3.2 - b.AddUint16(extensionRenegotiationInfo) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.secureRenegotiation) - }) - }) - } - if len(m.alpnProtocols) > 0 { - // RFC 7301, Section 3.1 - b.AddUint16(extensionALPN) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, proto := range m.alpnProtocols { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(proto)) - }) - } - }) - }) - } - if m.scts { - // RFC 6962, Section 3.3.1 - b.AddUint16(extensionSCT) - b.AddUint16(0) // empty extension_data - } - if len(m.supportedVersions) > 0 { - // RFC 8446, Section 4.2.1 - b.AddUint16(extensionSupportedVersions) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - for _, vers := range m.supportedVersions { - b.AddUint16(vers) - } - }) - }) - } - if len(m.cookie) > 0 { - // RFC 8446, Section 4.2.2 - b.AddUint16(extensionCookie) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.cookie) - }) - }) - } - if len(m.keyShares) > 0 { - // RFC 8446, Section 4.2.8 - b.AddUint16(extensionKeyShare) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, ks := range m.keyShares { - b.AddUint16(uint16(ks.group)) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ks.data) - }) - } - }) - }) - } - if m.earlyData { - // RFC 8446, Section 4.2.10 - b.AddUint16(extensionEarlyData) - b.AddUint16(0) // empty extension_data - } - if len(m.pskModes) > 0 { - // RFC 8446, Section 4.2.9 - b.AddUint16(extensionPSKModes) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.pskModes) - }) - }) - } - for _, ext := range m.additionalExtensions { - b.AddUint16(ext.Type) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ext.Data) - }) - } - if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension - // RFC 8446, Section 4.2.11 - b.AddUint16(extensionPreSharedKey) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, psk := range m.pskIdentities { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(psk.label) - }) - b.AddUint32(psk.obfuscatedTicketAge) - } - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, binder := range m.pskBinders { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(binder) - }) - } - }) - }) - } - - extensionsPresent = len(b.BytesOrPanic()) > 2 - }) - - if !extensionsPresent { - *b = bWithoutExtensions - } - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -// marshalWithoutBinders returns the ClientHello through the -// PreSharedKeyExtension.identities field, according to RFC 8446, Section -// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length. -func (m *clientHelloMsg) marshalWithoutBinders() []byte { - bindersLen := 2 // uint16 length prefix - for _, binder := range m.pskBinders { - bindersLen += 1 // uint8 length prefix - bindersLen += len(binder) - } - - fullMessage := m.marshal() - return fullMessage[:len(fullMessage)-bindersLen] -} - -// updateBinders updates the m.pskBinders field, if necessary updating the -// cached marshaled representation. The supplied binders must have the same -// length as the current m.pskBinders. -func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) { - if len(pskBinders) != len(m.pskBinders) { - panic("tls: internal error: pskBinders length mismatch") - } - for i := range m.pskBinders { - if len(pskBinders[i]) != len(m.pskBinders[i]) { - panic("tls: internal error: pskBinders length mismatch") - } - } - m.pskBinders = pskBinders - if m.raw != nil { - lenWithoutBinders := len(m.marshalWithoutBinders()) - // TODO(filippo): replace with NewFixedBuilder once CL 148882 is imported. - b := cryptobyte.NewBuilder(m.raw[:lenWithoutBinders]) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, binder := range m.pskBinders { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(binder) - }) - } - }) - if len(b.BytesOrPanic()) != len(m.raw) { - panic("tls: internal error: failed to update binders") - } - } -} - -func (m *clientHelloMsg) unmarshal(data []byte) bool { - *m = clientHelloMsg{raw: data} - s := cryptobyte.String(data) - - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) || - !readUint8LengthPrefixed(&s, &m.sessionId) { - return false - } - - var cipherSuites cryptobyte.String - if !s.ReadUint16LengthPrefixed(&cipherSuites) { - return false - } - m.cipherSuites = []uint16{} - m.secureRenegotiationSupported = false - for !cipherSuites.Empty() { - var suite uint16 - if !cipherSuites.ReadUint16(&suite) { - return false - } - if suite == scsvRenegotiation { - m.secureRenegotiationSupported = true - } - m.cipherSuites = append(m.cipherSuites, suite) - } - - if !readUint8LengthPrefixed(&s, &m.compressionMethods) { - return false - } - - if s.Empty() { - // ClientHello is optionally followed by extension data - return true - } - - var extensions cryptobyte.String - if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { - return false - } - - for !extensions.Empty() { - var ext uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&ext) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch ext { - case extensionServerName: - // RFC 6066, Section 3 - var nameList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() { - return false - } - for !nameList.Empty() { - var nameType uint8 - var serverName cryptobyte.String - if !nameList.ReadUint8(&nameType) || - !nameList.ReadUint16LengthPrefixed(&serverName) || - serverName.Empty() { - return false - } - if nameType != 0 { - continue - } - if len(m.serverName) != 0 { - // Multiple names of the same name_type are prohibited. - return false - } - m.serverName = string(serverName) - // An SNI value may not include a trailing dot. - if strings.HasSuffix(m.serverName, ".") { - return false - } - } - case extensionStatusRequest: - // RFC 4366, Section 3.6 - var statusType uint8 - var ignored cryptobyte.String - if !extData.ReadUint8(&statusType) || - !extData.ReadUint16LengthPrefixed(&ignored) || - !extData.ReadUint16LengthPrefixed(&ignored) { - return false - } - m.ocspStapling = statusType == statusTypeOCSP - case extensionSupportedCurves: - // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7 - var curves cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() { - return false - } - for !curves.Empty() { - var curve uint16 - if !curves.ReadUint16(&curve) { - return false - } - m.supportedCurves = append(m.supportedCurves, CurveID(curve)) - } - case extensionSupportedPoints: - // RFC 4492, Section 5.1.2 - if !readUint8LengthPrefixed(&extData, &m.supportedPoints) || - len(m.supportedPoints) == 0 { - return false - } - case extensionSessionTicket: - // RFC 5077, Section 3.2 - m.ticketSupported = true - extData.ReadBytes(&m.sessionTicket, len(extData)) - case extensionSignatureAlgorithms: - // RFC 5246, Section 7.4.1.4.1 - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithms = append( - m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg)) - } - case extensionSignatureAlgorithmsCert: - // RFC 8446, Section 4.2.3 - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithmsCert = append( - m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg)) - } - case extensionRenegotiationInfo: - // RFC 5746, Section 3.2 - if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) { - return false - } - m.secureRenegotiationSupported = true - case extensionALPN: - // RFC 7301, Section 3.1 - var protoList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { - return false - } - for !protoList.Empty() { - var proto cryptobyte.String - if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() { - return false - } - m.alpnProtocols = append(m.alpnProtocols, string(proto)) - } - case extensionSCT: - // RFC 6962, Section 3.3.1 - m.scts = true - case extensionSupportedVersions: - // RFC 8446, Section 4.2.1 - var versList cryptobyte.String - if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() { - return false - } - for !versList.Empty() { - var vers uint16 - if !versList.ReadUint16(&vers) { - return false - } - m.supportedVersions = append(m.supportedVersions, vers) - } - case extensionCookie: - // RFC 8446, Section 4.2.2 - if !readUint16LengthPrefixed(&extData, &m.cookie) || - len(m.cookie) == 0 { - return false - } - case extensionKeyShare: - // RFC 8446, Section 4.2.8 - var clientShares cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&clientShares) { - return false - } - for !clientShares.Empty() { - var ks keyShare - if !clientShares.ReadUint16((*uint16)(&ks.group)) || - !readUint16LengthPrefixed(&clientShares, &ks.data) || - len(ks.data) == 0 { - return false - } - m.keyShares = append(m.keyShares, ks) - } - case extensionEarlyData: - // RFC 8446, Section 4.2.10 - m.earlyData = true - case extensionPSKModes: - // RFC 8446, Section 4.2.9 - if !readUint8LengthPrefixed(&extData, &m.pskModes) { - return false - } - case extensionPreSharedKey: - // RFC 8446, Section 4.2.11 - if !extensions.Empty() { - return false // pre_shared_key must be the last extension - } - var identities cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() { - return false - } - for !identities.Empty() { - var psk pskIdentity - if !readUint16LengthPrefixed(&identities, &psk.label) || - !identities.ReadUint32(&psk.obfuscatedTicketAge) || - len(psk.label) == 0 { - return false - } - m.pskIdentities = append(m.pskIdentities, psk) - } - var binders cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() { - return false - } - for !binders.Empty() { - var binder []byte - if !readUint8LengthPrefixed(&binders, &binder) || - len(binder) == 0 { - return false - } - m.pskBinders = append(m.pskBinders, binder) - } - default: - m.additionalExtensions = append(m.additionalExtensions, Extension{Type: ext, Data: extData}) - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type serverHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuite uint16 - compressionMethod uint8 - ocspStapling bool - ticketSupported bool - secureRenegotiationSupported bool - secureRenegotiation []byte - alpnProtocol string - scts [][]byte - supportedVersion uint16 - serverShare keyShare - selectedIdentityPresent bool - selectedIdentity uint16 - supportedPoints []uint8 - - // HelloRetryRequest extensions - cookie []byte - selectedGroup CurveID -} - -func (m *serverHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeServerHello) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.vers) - addBytesWithLength(b, m.random, 32) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.sessionId) - }) - b.AddUint16(m.cipherSuite) - b.AddUint8(m.compressionMethod) - - // If extensions aren't present, omit them. - var extensionsPresent bool - bWithoutExtensions := *b - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.ocspStapling { - b.AddUint16(extensionStatusRequest) - b.AddUint16(0) // empty extension_data - } - if m.ticketSupported { - b.AddUint16(extensionSessionTicket) - b.AddUint16(0) // empty extension_data - } - if m.secureRenegotiationSupported { - b.AddUint16(extensionRenegotiationInfo) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.secureRenegotiation) - }) - }) - } - if len(m.alpnProtocol) > 0 { - b.AddUint16(extensionALPN) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.alpnProtocol)) - }) - }) - }) - } - if len(m.scts) > 0 { - b.AddUint16(extensionSCT) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sct := range m.scts { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(sct) - }) - } - }) - }) - } - if m.supportedVersion != 0 { - b.AddUint16(extensionSupportedVersions) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.supportedVersion) - }) - } - if m.serverShare.group != 0 { - b.AddUint16(extensionKeyShare) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(uint16(m.serverShare.group)) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.serverShare.data) - }) - }) - } - if m.selectedIdentityPresent { - b.AddUint16(extensionPreSharedKey) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(m.selectedIdentity) - }) - } - - if len(m.cookie) > 0 { - b.AddUint16(extensionCookie) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.cookie) - }) - }) - } - if m.selectedGroup != 0 { - b.AddUint16(extensionKeyShare) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16(uint16(m.selectedGroup)) - }) - } - if len(m.supportedPoints) > 0 { - b.AddUint16(extensionSupportedPoints) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.supportedPoints) - }) - }) - } - - extensionsPresent = len(b.BytesOrPanic()) > 2 - }) - - if !extensionsPresent { - *b = bWithoutExtensions - } - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *serverHelloMsg) unmarshal(data []byte) bool { - *m = serverHelloMsg{raw: data} - s := cryptobyte.String(data) - - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) || - !readUint8LengthPrefixed(&s, &m.sessionId) || - !s.ReadUint16(&m.cipherSuite) || - !s.ReadUint8(&m.compressionMethod) { - return false - } - - if s.Empty() { - // ServerHello is optionally followed by extension data - return true - } - - var extensions cryptobyte.String - if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { - return false - } - - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch extension { - case extensionStatusRequest: - m.ocspStapling = true - case extensionSessionTicket: - m.ticketSupported = true - case extensionRenegotiationInfo: - if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) { - return false - } - m.secureRenegotiationSupported = true - case extensionALPN: - var protoList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { - return false - } - var proto cryptobyte.String - if !protoList.ReadUint8LengthPrefixed(&proto) || - proto.Empty() || !protoList.Empty() { - return false - } - m.alpnProtocol = string(proto) - case extensionSCT: - var sctList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() { - return false - } - for !sctList.Empty() { - var sct []byte - if !readUint16LengthPrefixed(&sctList, &sct) || - len(sct) == 0 { - return false - } - m.scts = append(m.scts, sct) - } - case extensionSupportedVersions: - if !extData.ReadUint16(&m.supportedVersion) { - return false - } - case extensionCookie: - if !readUint16LengthPrefixed(&extData, &m.cookie) || - len(m.cookie) == 0 { - return false - } - case extensionKeyShare: - // This extension has different formats in SH and HRR, accept either - // and let the handshake logic decide. See RFC 8446, Section 4.2.8. - if len(extData) == 2 { - if !extData.ReadUint16((*uint16)(&m.selectedGroup)) { - return false - } - } else { - if !extData.ReadUint16((*uint16)(&m.serverShare.group)) || - !readUint16LengthPrefixed(&extData, &m.serverShare.data) { - return false - } - } - case extensionPreSharedKey: - m.selectedIdentityPresent = true - if !extData.ReadUint16(&m.selectedIdentity) { - return false - } - case extensionSupportedPoints: - // RFC 4492, Section 5.1.2 - if !readUint8LengthPrefixed(&extData, &m.supportedPoints) || - len(m.supportedPoints) == 0 { - return false - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type encryptedExtensionsMsg struct { - raw []byte - alpnProtocol string - earlyData bool - - additionalExtensions []Extension -} - -func (m *encryptedExtensionsMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeEncryptedExtensions) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if len(m.alpnProtocol) > 0 { - b.AddUint16(extensionALPN) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.alpnProtocol)) - }) - }) - }) - } - if m.earlyData { - // RFC 8446, Section 4.2.10 - b.AddUint16(extensionEarlyData) - b.AddUint16(0) // empty extension_data - } - for _, ext := range m.additionalExtensions { - b.AddUint16(ext.Type) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ext.Data) - }) - } - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool { - *m = encryptedExtensionsMsg{raw: data} - s := cryptobyte.String(data) - - var extensions cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() { - return false - } - - for !extensions.Empty() { - var ext uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&ext) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch ext { - case extensionALPN: - var protoList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() { - return false - } - var proto cryptobyte.String - if !protoList.ReadUint8LengthPrefixed(&proto) || - proto.Empty() || !protoList.Empty() { - return false - } - m.alpnProtocol = string(proto) - case extensionEarlyData: - m.earlyData = true - default: - m.additionalExtensions = append(m.additionalExtensions, Extension{Type: ext, Data: extData}) - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type endOfEarlyDataMsg struct{} - -func (m *endOfEarlyDataMsg) marshal() []byte { - x := make([]byte, 4) - x[0] = typeEndOfEarlyData - return x -} - -func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} - -type keyUpdateMsg struct { - raw []byte - updateRequested bool -} - -func (m *keyUpdateMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeKeyUpdate) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - if m.updateRequested { - b.AddUint8(1) - } else { - b.AddUint8(0) - } - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *keyUpdateMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - - var updateRequested uint8 - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8(&updateRequested) || !s.Empty() { - return false - } - switch updateRequested { - case 0: - m.updateRequested = false - case 1: - m.updateRequested = true - default: - return false - } - return true -} - -type newSessionTicketMsgTLS13 struct { - raw []byte - lifetime uint32 - ageAdd uint32 - nonce []byte - label []byte - maxEarlyData uint32 -} - -func (m *newSessionTicketMsgTLS13) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeNewSessionTicket) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint32(m.lifetime) - b.AddUint32(m.ageAdd) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.nonce) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.label) - }) - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.maxEarlyData > 0 { - b.AddUint16(extensionEarlyData) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint32(m.maxEarlyData) - }) - } - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool { - *m = newSessionTicketMsgTLS13{raw: data} - s := cryptobyte.String(data) - - var extensions cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint32(&m.lifetime) || - !s.ReadUint32(&m.ageAdd) || - !readUint8LengthPrefixed(&s, &m.nonce) || - !readUint16LengthPrefixed(&s, &m.label) || - !s.ReadUint16LengthPrefixed(&extensions) || - !s.Empty() { - return false - } - - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch extension { - case extensionEarlyData: - if !extData.ReadUint32(&m.maxEarlyData) { - return false - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type certificateRequestMsgTLS13 struct { - raw []byte - ocspStapling bool - scts bool - supportedSignatureAlgorithms []SignatureScheme - supportedSignatureAlgorithmsCert []SignatureScheme - certificateAuthorities [][]byte -} - -func (m *certificateRequestMsgTLS13) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificateRequest) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - // certificate_request_context (SHALL be zero length unless used for - // post-handshake authentication) - b.AddUint8(0) - - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if m.ocspStapling { - b.AddUint16(extensionStatusRequest) - b.AddUint16(0) // empty extension_data - } - if m.scts { - // RFC 8446, Section 4.4.2.1 makes no mention of - // signed_certificate_timestamp in CertificateRequest, but - // "Extensions in the Certificate message from the client MUST - // correspond to extensions in the CertificateRequest message - // from the server." and it appears in the table in Section 4.2. - b.AddUint16(extensionSCT) - b.AddUint16(0) // empty extension_data - } - if len(m.supportedSignatureAlgorithms) > 0 { - b.AddUint16(extensionSignatureAlgorithms) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithms { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if len(m.supportedSignatureAlgorithmsCert) > 0 { - b.AddUint16(extensionSignatureAlgorithmsCert) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sigAlgo := range m.supportedSignatureAlgorithmsCert { - b.AddUint16(uint16(sigAlgo)) - } - }) - }) - } - if len(m.certificateAuthorities) > 0 { - b.AddUint16(extensionCertificateAuthorities) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, ca := range m.certificateAuthorities { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(ca) - }) - } - }) - }) - } - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool { - *m = certificateRequestMsgTLS13{raw: data} - s := cryptobyte.String(data) - - var context, extensions cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8LengthPrefixed(&context) || !context.Empty() || - !s.ReadUint16LengthPrefixed(&extensions) || - !s.Empty() { - return false - } - - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - - switch extension { - case extensionStatusRequest: - m.ocspStapling = true - case extensionSCT: - m.scts = true - case extensionSignatureAlgorithms: - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithms = append( - m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg)) - } - case extensionSignatureAlgorithmsCert: - var sigAndAlgs cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() { - return false - } - for !sigAndAlgs.Empty() { - var sigAndAlg uint16 - if !sigAndAlgs.ReadUint16(&sigAndAlg) { - return false - } - m.supportedSignatureAlgorithmsCert = append( - m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg)) - } - case extensionCertificateAuthorities: - var auths cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() { - return false - } - for !auths.Empty() { - var ca []byte - if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 { - return false - } - m.certificateAuthorities = append(m.certificateAuthorities, ca) - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - - return true -} - -type certificateMsg struct { - raw []byte - certificates [][]byte -} - -func (m *certificateMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - var i int - for _, slice := range m.certificates { - i += len(slice) - } - - length := 3 + 3*len(m.certificates) + i - x = make([]byte, 4+length) - x[0] = typeCertificate - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - certificateOctets := length - 3 - x[4] = uint8(certificateOctets >> 16) - x[5] = uint8(certificateOctets >> 8) - x[6] = uint8(certificateOctets) - - y := x[7:] - for _, slice := range m.certificates { - y[0] = uint8(len(slice) >> 16) - y[1] = uint8(len(slice) >> 8) - y[2] = uint8(len(slice)) - copy(y[3:], slice) - y = y[3+len(slice):] - } - - m.raw = x - return -} - -func (m *certificateMsg) unmarshal(data []byte) bool { - if len(data) < 7 { - return false - } - - m.raw = data - certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6]) - if uint32(len(data)) != certsLen+7 { - return false - } - - numCerts := 0 - d := data[7:] - for certsLen > 0 { - if len(d) < 4 { - return false - } - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - if uint32(len(d)) < 3+certLen { - return false - } - d = d[3+certLen:] - certsLen -= 3 + certLen - numCerts++ - } - - m.certificates = make([][]byte, numCerts) - d = data[7:] - for i := 0; i < numCerts; i++ { - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - m.certificates[i] = d[3 : 3+certLen] - d = d[3+certLen:] - } - - return true -} - -type certificateMsgTLS13 struct { - raw []byte - certificate Certificate - ocspStapling bool - scts bool -} - -func (m *certificateMsgTLS13) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificate) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(0) // certificate_request_context - - certificate := m.certificate - if !m.ocspStapling { - certificate.OCSPStaple = nil - } - if !m.scts { - certificate.SignedCertificateTimestamps = nil - } - marshalCertificate(b, certificate) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) { - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - for i, cert := range certificate.Certificate { - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(cert) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - if i > 0 { - // This library only supports OCSP and SCT for leaf certificates. - return - } - if certificate.OCSPStaple != nil { - b.AddUint16(extensionStatusRequest) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(statusTypeOCSP) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(certificate.OCSPStaple) - }) - }) - } - if certificate.SignedCertificateTimestamps != nil { - b.AddUint16(extensionSCT) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - for _, sct := range certificate.SignedCertificateTimestamps { - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(sct) - }) - } - }) - }) - } - }) - } - }) -} - -func (m *certificateMsgTLS13) unmarshal(data []byte) bool { - *m = certificateMsgTLS13{raw: data} - s := cryptobyte.String(data) - - var context cryptobyte.String - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8LengthPrefixed(&context) || !context.Empty() || - !unmarshalCertificate(&s, &m.certificate) || - !s.Empty() { - return false - } - - m.scts = m.certificate.SignedCertificateTimestamps != nil - m.ocspStapling = m.certificate.OCSPStaple != nil - - return true -} - -func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool { - var certList cryptobyte.String - if !s.ReadUint24LengthPrefixed(&certList) { - return false - } - for !certList.Empty() { - var cert []byte - var extensions cryptobyte.String - if !readUint24LengthPrefixed(&certList, &cert) || - !certList.ReadUint16LengthPrefixed(&extensions) { - return false - } - certificate.Certificate = append(certificate.Certificate, cert) - for !extensions.Empty() { - var extension uint16 - var extData cryptobyte.String - if !extensions.ReadUint16(&extension) || - !extensions.ReadUint16LengthPrefixed(&extData) { - return false - } - if len(certificate.Certificate) > 1 { - // This library only supports OCSP and SCT for leaf certificates. - continue - } - - switch extension { - case extensionStatusRequest: - var statusType uint8 - if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP || - !readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) || - len(certificate.OCSPStaple) == 0 { - return false - } - case extensionSCT: - var sctList cryptobyte.String - if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() { - return false - } - for !sctList.Empty() { - var sct []byte - if !readUint16LengthPrefixed(&sctList, &sct) || - len(sct) == 0 { - return false - } - certificate.SignedCertificateTimestamps = append( - certificate.SignedCertificateTimestamps, sct) - } - default: - // Ignore unknown extensions. - continue - } - - if !extData.Empty() { - return false - } - } - } - return true -} - -type serverKeyExchangeMsg struct { - raw []byte - key []byte -} - -func (m *serverKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.key) - x := make([]byte, length+4) - x[0] = typeServerKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.key) - - m.raw = x - return x -} - -func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - m.key = data[4:] - return true -} - -type certificateStatusMsg struct { - raw []byte - response []byte -} - -func (m *certificateStatusMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificateStatus) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddUint8(statusTypeOCSP) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.response) - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *certificateStatusMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - - var statusType uint8 - if !s.Skip(4) || // message type and uint24 length field - !s.ReadUint8(&statusType) || statusType != statusTypeOCSP || - !readUint24LengthPrefixed(&s, &m.response) || - len(m.response) == 0 || !s.Empty() { - return false - } - return true -} - -type serverHelloDoneMsg struct{} - -func (m *serverHelloDoneMsg) marshal() []byte { - x := make([]byte, 4) - x[0] = typeServerHelloDone - return x -} - -func (m *serverHelloDoneMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} - -type clientKeyExchangeMsg struct { - raw []byte - ciphertext []byte -} - -func (m *clientKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.ciphertext) - x := make([]byte, length+4) - x[0] = typeClientKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.ciphertext) - - m.raw = x - return x -} - -func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - l := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if l != len(data)-4 { - return false - } - m.ciphertext = data[4:] - return true -} - -type finishedMsg struct { - raw []byte - verifyData []byte -} - -func (m *finishedMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeFinished) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.verifyData) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *finishedMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - return s.Skip(1) && - readUint24LengthPrefixed(&s, &m.verifyData) && - s.Empty() -} - -type certificateRequestMsg struct { - raw []byte - // hasSignatureAlgorithm indicates whether this message includes a list of - // supported signature algorithms. This change was introduced with TLS 1.2. - hasSignatureAlgorithm bool - - certificateTypes []byte - supportedSignatureAlgorithms []SignatureScheme - certificateAuthorities [][]byte -} - -func (m *certificateRequestMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See RFC 4346, Section 7.4.4. - length := 1 + len(m.certificateTypes) + 2 - casLength := 0 - for _, ca := range m.certificateAuthorities { - casLength += 2 + len(ca) - } - length += casLength - - if m.hasSignatureAlgorithm { - length += 2 + 2*len(m.supportedSignatureAlgorithms) - } - - x = make([]byte, 4+length) - x[0] = typeCertificateRequest - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - x[4] = uint8(len(m.certificateTypes)) - - copy(x[5:], m.certificateTypes) - y := x[5+len(m.certificateTypes):] - - if m.hasSignatureAlgorithm { - n := len(m.supportedSignatureAlgorithms) * 2 - y[0] = uint8(n >> 8) - y[1] = uint8(n) - y = y[2:] - for _, sigAlgo := range m.supportedSignatureAlgorithms { - y[0] = uint8(sigAlgo >> 8) - y[1] = uint8(sigAlgo) - y = y[2:] - } - } - - y[0] = uint8(casLength >> 8) - y[1] = uint8(casLength) - y = y[2:] - for _, ca := range m.certificateAuthorities { - y[0] = uint8(len(ca) >> 8) - y[1] = uint8(len(ca)) - y = y[2:] - copy(y, ca) - y = y[len(ca):] - } - - m.raw = x - return -} - -func (m *certificateRequestMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 5 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - numCertTypes := int(data[4]) - data = data[5:] - if numCertTypes == 0 || len(data) <= numCertTypes { - return false - } - - m.certificateTypes = make([]byte, numCertTypes) - if copy(m.certificateTypes, data) != numCertTypes { - return false - } - - data = data[numCertTypes:] - - if m.hasSignatureAlgorithm { - if len(data) < 2 { - return false - } - sigAndHashLen := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if sigAndHashLen&1 != 0 { - return false - } - if len(data) < int(sigAndHashLen) { - return false - } - numSigAlgos := sigAndHashLen / 2 - m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos) - for i := range m.supportedSignatureAlgorithms { - m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1]) - data = data[2:] - } - } - - if len(data) < 2 { - return false - } - casLength := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if len(data) < int(casLength) { - return false - } - cas := make([]byte, casLength) - copy(cas, data) - data = data[casLength:] - - m.certificateAuthorities = nil - for len(cas) > 0 { - if len(cas) < 2 { - return false - } - caLen := uint16(cas[0])<<8 | uint16(cas[1]) - cas = cas[2:] - - if len(cas) < int(caLen) { - return false - } - - m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen]) - cas = cas[caLen:] - } - - return len(data) == 0 -} - -type certificateVerifyMsg struct { - raw []byte - hasSignatureAlgorithm bool // format change introduced in TLS 1.2 - signatureAlgorithm SignatureScheme - signature []byte -} - -func (m *certificateVerifyMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - var b cryptobyte.Builder - b.AddUint8(typeCertificateVerify) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - if m.hasSignatureAlgorithm { - b.AddUint16(uint16(m.signatureAlgorithm)) - } - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.signature) - }) - }) - - m.raw = b.BytesOrPanic() - return m.raw -} - -func (m *certificateVerifyMsg) unmarshal(data []byte) bool { - m.raw = data - s := cryptobyte.String(data) - - if !s.Skip(4) { // message type and uint24 length field - return false - } - if m.hasSignatureAlgorithm { - if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) { - return false - } - } - return readUint16LengthPrefixed(&s, &m.signature) && s.Empty() -} - -type newSessionTicketMsg struct { - raw []byte - ticket []byte -} - -func (m *newSessionTicketMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See RFC 5077, Section 3.3. - ticketLen := len(m.ticket) - length := 2 + 4 + ticketLen - x = make([]byte, 4+length) - x[0] = typeNewSessionTicket - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[8] = uint8(ticketLen >> 8) - x[9] = uint8(ticketLen) - copy(x[10:], m.ticket) - - m.raw = x - - return -} - -func (m *newSessionTicketMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 10 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - ticketLen := int(data[8])<<8 + int(data[9]) - if len(data)-10 != ticketLen { - return false - } - - m.ticket = data[10:] - - return true -} - -type helloRequestMsg struct { -} - -func (*helloRequestMsg) marshal() []byte { - return []byte{typeHelloRequest, 0, 0, 0} -} - -func (*helloRequestMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_server.go b/vendor/github.com/marten-seemann/qtls-go1-17/handshake_server.go deleted file mode 100644 index 7d3557d72..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_server.go +++ /dev/null @@ -1,905 +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 qtls - -import ( - "context" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "errors" - "fmt" - "hash" - "io" - "sync/atomic" - "time" -) - -// serverHandshakeState contains details of a server handshake in progress. -// It's discarded once the handshake has completed. -type serverHandshakeState struct { - c *Conn - ctx context.Context - clientHello *clientHelloMsg - hello *serverHelloMsg - suite *cipherSuite - ecdheOk bool - ecSignOk bool - rsaDecryptOk bool - rsaSignOk bool - sessionState *sessionState - finishedHash finishedHash - masterSecret []byte - cert *Certificate -} - -// serverHandshake performs a TLS handshake as a server. -func (c *Conn) serverHandshake(ctx context.Context) error { - c.setAlternativeRecordLayer() - - clientHello, err := c.readClientHello(ctx) - if err != nil { - return err - } - - if c.vers == VersionTLS13 { - hs := serverHandshakeStateTLS13{ - c: c, - ctx: ctx, - clientHello: clientHello, - } - return hs.handshake() - } else if c.extraConfig.usesAlternativeRecordLayer() { - // This should already have been caught by the check that the ClientHello doesn't - // offer any (supported) versions older than TLS 1.3. - // Check again to make sure we can't be tricked into using an older version. - c.sendAlert(alertProtocolVersion) - return errors.New("tls: negotiated TLS < 1.3 when using QUIC") - } - - hs := serverHandshakeState{ - c: c, - ctx: ctx, - clientHello: clientHello, - } - return hs.handshake() -} - -func (hs *serverHandshakeState) handshake() error { - c := hs.c - - if err := hs.processClientHello(); err != nil { - return err - } - - // For an overview of TLS handshaking, see RFC 5246, Section 7.3. - c.buffering = true - if hs.checkForResumption() { - // The client has included a session ticket and so we do an abbreviated handshake. - c.didResume = true - if err := hs.doResumeHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.sendSessionTicket(); err != nil { - return err - } - if err := hs.sendFinished(c.serverFinished[:]); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - c.clientFinishedIsFirst = false - if err := hs.readFinished(nil); err != nil { - return err - } - } else { - // The client didn't include a session ticket, or it wasn't - // valid so we do a full handshake. - if err := hs.pickCipherSuite(); err != nil { - return err - } - if err := hs.doFullHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.readFinished(c.clientFinished[:]); err != nil { - return err - } - c.clientFinishedIsFirst = true - c.buffering = true - if err := hs.sendSessionTicket(); err != nil { - return err - } - if err := hs.sendFinished(nil); err != nil { - return err - } - if _, err := c.flush(); err != nil { - return err - } - } - - c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random) - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -// readClientHello reads a ClientHello message and selects the protocol version. -func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) { - msg, err := c.readHandshake() - if err != nil { - return nil, err - } - clientHello, ok := msg.(*clientHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return nil, unexpectedMessageError(clientHello, msg) - } - - var configForClient *config - originalConfig := c.config - if c.config.GetConfigForClient != nil { - chi := newClientHelloInfo(ctx, c, clientHello) - if cfc, err := c.config.GetConfigForClient(chi); err != nil { - c.sendAlert(alertInternalError) - return nil, err - } else if cfc != nil { - configForClient = fromConfig(cfc) - c.config = configForClient - } - } - c.ticketKeys = originalConfig.ticketKeys(configForClient) - - clientVersions := clientHello.supportedVersions - if len(clientHello.supportedVersions) == 0 { - clientVersions = supportedVersionsFromMax(clientHello.vers) - } - if c.extraConfig.usesAlternativeRecordLayer() { - // In QUIC, the client MUST NOT offer any old TLS versions. - // Here, we can only check that none of the other supported versions of this library - // (TLS 1.0 - TLS 1.2) is offered. We don't check for any SSL versions here. - for _, ver := range clientVersions { - if ver == VersionTLS13 { - continue - } - for _, v := range supportedVersions { - if ver == v { - c.sendAlert(alertProtocolVersion) - return nil, fmt.Errorf("tls: client offered old TLS version %#x", ver) - } - } - } - // Make the config we're using allows us to use TLS 1.3. - if c.config.maxSupportedVersion() < VersionTLS13 { - c.sendAlert(alertInternalError) - return nil, errors.New("tls: MaxVersion prevents QUIC from using TLS 1.3") - } - } - c.vers, ok = c.config.mutualVersion(clientVersions) - if !ok { - c.sendAlert(alertProtocolVersion) - return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions) - } - c.haveVers = true - c.in.version = c.vers - c.out.version = c.vers - - return clientHello, nil -} - -func (hs *serverHandshakeState) processClientHello() error { - c := hs.c - - hs.hello = new(serverHelloMsg) - hs.hello.vers = c.vers - - foundCompression := false - // We only support null compression, so check that the client offered it. - for _, compression := range hs.clientHello.compressionMethods { - if compression == compressionNone { - foundCompression = true - break - } - } - - if !foundCompression { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: client does not support uncompressed connections") - } - - hs.hello.random = make([]byte, 32) - serverRandom := hs.hello.random - // Downgrade protection canaries. See RFC 8446, Section 4.1.3. - maxVers := c.config.maxSupportedVersion() - if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary { - if c.vers == VersionTLS12 { - copy(serverRandom[24:], downgradeCanaryTLS12) - } else { - copy(serverRandom[24:], downgradeCanaryTLS11) - } - serverRandom = serverRandom[:24] - } - _, err := io.ReadFull(c.config.rand(), serverRandom) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - if len(hs.clientHello.secureRenegotiation) != 0 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: initial handshake had non-empty renegotiation extension") - } - - hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported - hs.hello.compressionMethod = compressionNone - if len(hs.clientHello.serverName) > 0 { - c.serverName = hs.clientHello.serverName - } - - selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols) - if err != nil { - c.sendAlert(alertNoApplicationProtocol) - return err - } - hs.hello.alpnProtocol = selectedProto - c.clientProtocol = selectedProto - - hs.cert, err = c.config.getCertificate(newClientHelloInfo(hs.ctx, c, hs.clientHello)) - if err != nil { - if err == errNoCertificates { - c.sendAlert(alertUnrecognizedName) - } else { - c.sendAlert(alertInternalError) - } - return err - } - if hs.clientHello.scts { - hs.hello.scts = hs.cert.SignedCertificateTimestamps - } - - hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints) - - if hs.ecdheOk { - // Although omitting the ec_point_formats extension is permitted, some - // old OpenSSL version will refuse to handshake if not present. - // - // Per RFC 4492, section 5.1.2, implementations MUST support the - // uncompressed point format. See golang.org/issue/31943. - hs.hello.supportedPoints = []uint8{pointFormatUncompressed} - } - - if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok { - switch priv.Public().(type) { - case *ecdsa.PublicKey: - hs.ecSignOk = true - case ed25519.PublicKey: - hs.ecSignOk = true - case *rsa.PublicKey: - hs.rsaSignOk = true - default: - c.sendAlert(alertInternalError) - return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public()) - } - } - if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok { - switch priv.Public().(type) { - case *rsa.PublicKey: - hs.rsaDecryptOk = true - default: - c.sendAlert(alertInternalError) - return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public()) - } - } - - return nil -} - -// negotiateALPN picks a shared ALPN protocol that both sides support in server -// preference order. If ALPN is not configured or the peer doesn't support it, -// it returns "" and no error. -func negotiateALPN(serverProtos, clientProtos []string) (string, error) { - if len(serverProtos) == 0 || len(clientProtos) == 0 { - return "", nil - } - var http11fallback bool - for _, s := range serverProtos { - for _, c := range clientProtos { - if s == c { - return s, nil - } - if s == "h2" && c == "http/1.1" { - http11fallback = true - } - } - } - // As a special case, let http/1.1 clients connect to h2 servers as if they - // didn't support ALPN. We used not to enforce protocol overlap, so over - // time a number of HTTP servers were configured with only "h2", but - // expected to accept connections from "http/1.1" clients. See Issue 46310. - if http11fallback { - return "", nil - } - return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos) -} - -// supportsECDHE returns whether ECDHE key exchanges can be used with this -// pre-TLS 1.3 client. -func supportsECDHE(c *config, supportedCurves []CurveID, supportedPoints []uint8) bool { - supportsCurve := false - for _, curve := range supportedCurves { - if c.supportsCurve(curve) { - supportsCurve = true - break - } - } - - supportsPointFormat := false - for _, pointFormat := range supportedPoints { - if pointFormat == pointFormatUncompressed { - supportsPointFormat = true - break - } - } - - return supportsCurve && supportsPointFormat -} - -func (hs *serverHandshakeState) pickCipherSuite() error { - c := hs.c - - preferenceOrder := cipherSuitesPreferenceOrder - if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { - preferenceOrder = cipherSuitesPreferenceOrderNoAES - } - - configCipherSuites := c.config.cipherSuites() - preferenceList := make([]uint16, 0, len(configCipherSuites)) - for _, suiteID := range preferenceOrder { - for _, id := range configCipherSuites { - if id == suiteID { - preferenceList = append(preferenceList, id) - break - } - } - } - - hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk) - if hs.suite == nil { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: no cipher suite supported by both client and server") - } - c.cipherSuite = hs.suite.id - - for _, id := range hs.clientHello.cipherSuites { - if id == TLS_FALLBACK_SCSV { - // The client is doing a fallback connection. See RFC 7507. - if hs.clientHello.vers < c.config.maxSupportedVersion() { - c.sendAlert(alertInappropriateFallback) - return errors.New("tls: client using inappropriate protocol fallback") - } - break - } - } - - return nil -} - -func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool { - if c.flags&suiteECDHE != 0 { - if !hs.ecdheOk { - return false - } - if c.flags&suiteECSign != 0 { - if !hs.ecSignOk { - return false - } - } else if !hs.rsaSignOk { - return false - } - } else if !hs.rsaDecryptOk { - return false - } - if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 { - return false - } - return true -} - -// checkForResumption reports whether we should perform resumption on this connection. -func (hs *serverHandshakeState) checkForResumption() bool { - c := hs.c - - if c.config.SessionTicketsDisabled { - return false - } - - plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket) - if plaintext == nil { - return false - } - hs.sessionState = &sessionState{usedOldKey: usedOldKey} - ok := hs.sessionState.unmarshal(plaintext) - if !ok { - return false - } - - createdAt := time.Unix(int64(hs.sessionState.createdAt), 0) - if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { - return false - } - - // Never resume a session for a different TLS version. - if c.vers != hs.sessionState.vers { - return false - } - - cipherSuiteOk := false - // Check that the client is still offering the ciphersuite in the session. - for _, id := range hs.clientHello.cipherSuites { - if id == hs.sessionState.cipherSuite { - cipherSuiteOk = true - break - } - } - if !cipherSuiteOk { - return false - } - - // Check that we also support the ciphersuite from the session. - hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite}, - c.config.cipherSuites(), hs.cipherSuiteOk) - if hs.suite == nil { - return false - } - - sessionHasClientCerts := len(hs.sessionState.certificates) != 0 - needClientCerts := requiresClientCert(c.config.ClientAuth) - if needClientCerts && !sessionHasClientCerts { - return false - } - if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { - return false - } - - return true -} - -func (hs *serverHandshakeState) doResumeHandshake() error { - c := hs.c - - hs.hello.cipherSuite = hs.suite.id - c.cipherSuite = hs.suite.id - // We echo the client's session ID in the ServerHello to let it know - // that we're doing a resumption. - hs.hello.sessionId = hs.clientHello.sessionId - hs.hello.ticketSupported = hs.sessionState.usedOldKey - hs.finishedHash = newFinishedHash(c.vers, hs.suite) - hs.finishedHash.discardHandshakeBuffer() - hs.finishedHash.Write(hs.clientHello.marshal()) - hs.finishedHash.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - if err := c.processCertsFromClient(Certificate{ - Certificate: hs.sessionState.certificates, - }); err != nil { - return err - } - - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - hs.masterSecret = hs.sessionState.masterSecret - - return nil -} - -func (hs *serverHandshakeState) doFullHandshake() error { - c := hs.c - - if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { - hs.hello.ocspStapling = true - } - - hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled - hs.hello.cipherSuite = hs.suite.id - - hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite) - if c.config.ClientAuth == NoClientCert { - // No need to keep a full record of the handshake if client - // certificates won't be used. - hs.finishedHash.discardHandshakeBuffer() - } - hs.finishedHash.Write(hs.clientHello.marshal()) - hs.finishedHash.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - certMsg := new(certificateMsg) - certMsg.certificates = hs.cert.Certificate - hs.finishedHash.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - - if hs.hello.ocspStapling { - certStatus := new(certificateStatusMsg) - certStatus.response = hs.cert.OCSPStaple - hs.finishedHash.Write(certStatus.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certStatus.marshal()); err != nil { - return err - } - } - - keyAgreement := hs.suite.ka(c.vers) - skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - if skx != nil { - hs.finishedHash.Write(skx.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, skx.marshal()); err != nil { - return err - } - } - - var certReq *certificateRequestMsg - if c.config.ClientAuth >= RequestClientCert { - // Request a client certificate - certReq = new(certificateRequestMsg) - certReq.certificateTypes = []byte{ - byte(certTypeRSASign), - byte(certTypeECDSASign), - } - if c.vers >= VersionTLS12 { - certReq.hasSignatureAlgorithm = true - certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms - } - - // An empty list of certificateAuthorities signals to - // the client that it may send any certificate in response - // to our request. When we know the CAs we trust, then - // we can send them down, so that the client can choose - // an appropriate certificate to give to us. - if c.config.ClientCAs != nil { - certReq.certificateAuthorities = c.config.ClientCAs.Subjects() - } - hs.finishedHash.Write(certReq.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { - return err - } - } - - helloDone := new(serverHelloDoneMsg) - hs.finishedHash.Write(helloDone.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, helloDone.marshal()); err != nil { - return err - } - - if _, err := c.flush(); err != nil { - return err - } - - var pub crypto.PublicKey // public key for client auth, if any - - msg, err := c.readHandshake() - if err != nil { - return err - } - - // If we requested a client certificate, then the client must send a - // certificate message, even if it's empty. - if c.config.ClientAuth >= RequestClientCert { - certMsg, ok := msg.(*certificateMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - hs.finishedHash.Write(certMsg.marshal()) - - if err := c.processCertsFromClient(Certificate{ - Certificate: certMsg.certificates, - }); err != nil { - return err - } - if len(certMsg.certificates) != 0 { - pub = c.peerCertificates[0].PublicKey - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - // Get client key exchange - ckx, ok := msg.(*clientKeyExchangeMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(ckx, msg) - } - hs.finishedHash.Write(ckx.marshal()) - - preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.clientHello.random, hs.hello.random) - if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil { - c.sendAlert(alertInternalError) - return err - } - - // If we received a client cert in response to our certificate request message, - // the client will send us a certificateVerifyMsg immediately after the - // clientKeyExchangeMsg. This message is a digest of all preceding - // handshake-layer messages that is signed using the private key corresponding - // to the client's certificate. This allows us to verify that the client is in - // possession of the private key of the certificate. - if len(c.peerCertificates) > 0 { - msg, err = c.readHandshake() - if err != nil { - return err - } - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certVerify, msg) - } - - var sigType uint8 - var sigHash crypto.Hash - if c.vers >= VersionTLS12 { - if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client certificate used with invalid signature algorithm") - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub) - if err != nil { - c.sendAlert(alertIllegalParameter) - return err - } - } - - signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash, hs.masterSecret) - if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid signature by the client certificate: " + err.Error()) - } - - hs.finishedHash.Write(certVerify.marshal()) - } - - hs.finishedHash.discardHandshakeBuffer() - - return nil -} - -func (hs *serverHandshakeState) establishKeys() error { - c := hs.c - - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) - - var clientCipher, serverCipher interface{} - var clientHash, serverHash hash.Hash - - if hs.suite.aead == nil { - clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) - clientHash = hs.suite.mac(clientMAC) - serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) - serverHash = hs.suite.mac(serverMAC) - } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) - } - - c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) - c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) - - return nil -} - -func (hs *serverHandshakeState) readFinished(out []byte) error { - c := hs.c - - if err := c.readChangeCipherSpec(); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - clientFinished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(clientFinished, msg) - } - - verify := hs.finishedHash.clientSum(hs.masterSecret) - if len(verify) != len(clientFinished.verifyData) || - subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: client's Finished message is incorrect") - } - - hs.finishedHash.Write(clientFinished.marshal()) - copy(out, verify) - return nil -} - -func (hs *serverHandshakeState) sendSessionTicket() error { - // ticketSupported is set in a resumption handshake if the - // ticket from the client was encrypted with an old session - // ticket key and thus a refreshed ticket should be sent. - if !hs.hello.ticketSupported { - return nil - } - - c := hs.c - m := new(newSessionTicketMsg) - - createdAt := uint64(c.config.time().Unix()) - if hs.sessionState != nil { - // If this is re-wrapping an old key, then keep - // the original time it was created. - createdAt = hs.sessionState.createdAt - } - - var certsFromClient [][]byte - for _, cert := range c.peerCertificates { - certsFromClient = append(certsFromClient, cert.Raw) - } - state := sessionState{ - vers: c.vers, - cipherSuite: hs.suite.id, - createdAt: createdAt, - masterSecret: hs.masterSecret, - certificates: certsFromClient, - } - var err error - m.ticket, err = c.encryptTicket(state.marshal()) - if err != nil { - return err - } - - hs.finishedHash.Write(m.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeState) sendFinished(out []byte) error { - c := hs.c - - if _, err := c.writeRecord(recordTypeChangeCipherSpec, []byte{1}); err != nil { - return err - } - - finished := new(finishedMsg) - finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) - hs.finishedHash.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - - copy(out, finished.verifyData) - - return nil -} - -// processCertsFromClient takes a chain of client certificates either from a -// Certificates message or from a sessionState and verifies them. It returns -// the public key of the leaf certificate. -func (c *Conn) processCertsFromClient(certificate Certificate) error { - certificates := certificate.Certificate - certs := make([]*x509.Certificate, len(certificates)) - var err error - for i, asn1Data := range certificates { - if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to parse client certificate: " + err.Error()) - } - } - - if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) { - c.sendAlert(alertBadCertificate) - return errors.New("tls: client didn't provide a certificate") - } - - if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { - opts := x509.VerifyOptions{ - Roots: c.config.ClientCAs, - CurrentTime: c.config.time(), - Intermediates: x509.NewCertPool(), - KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, - } - - for _, cert := range certs[1:] { - opts.Intermediates.AddCert(cert) - } - - chains, err := certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("tls: failed to verify client certificate: " + err.Error()) - } - - c.verifiedChains = chains - } - - c.peerCertificates = certs - c.ocspResponse = certificate.OCSPStaple - c.scts = certificate.SignedCertificateTimestamps - - if len(certs) > 0 { - switch certs[0].PublicKey.(type) { - case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey: - default: - c.sendAlert(alertUnsupportedCertificate) - return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey) - } - } - - if c.config.VerifyPeerCertificate != nil { - if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - return nil -} - -func newClientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo { - supportedVersions := clientHello.supportedVersions - if len(clientHello.supportedVersions) == 0 { - supportedVersions = supportedVersionsFromMax(clientHello.vers) - } - - return toClientHelloInfo(&clientHelloInfo{ - CipherSuites: clientHello.cipherSuites, - ServerName: clientHello.serverName, - SupportedCurves: clientHello.supportedCurves, - SupportedPoints: clientHello.supportedPoints, - SignatureSchemes: clientHello.supportedSignatureAlgorithms, - SupportedProtos: clientHello.alpnProtocols, - SupportedVersions: supportedVersions, - Conn: c.conn, - config: toConfig(c.config), - ctx: ctx, - }) -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_server_tls13.go b/vendor/github.com/marten-seemann/qtls-go1-17/handshake_server_tls13.go deleted file mode 100644 index 0c200605e..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/handshake_server_tls13.go +++ /dev/null @@ -1,896 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "bytes" - "context" - "crypto" - "crypto/hmac" - "crypto/rsa" - "errors" - "hash" - "io" - "sync/atomic" - "time" -) - -// maxClientPSKIdentities is the number of client PSK identities the server will -// attempt to validate. It will ignore the rest not to let cheap ClientHello -// messages cause too much work in session ticket decryption attempts. -const maxClientPSKIdentities = 5 - -type serverHandshakeStateTLS13 struct { - c *Conn - ctx context.Context - clientHello *clientHelloMsg - hello *serverHelloMsg - alpnNegotiationErr error - encryptedExtensions *encryptedExtensionsMsg - sentDummyCCS bool - usingPSK bool - suite *cipherSuiteTLS13 - cert *Certificate - sigAlg SignatureScheme - earlySecret []byte - sharedKey []byte - handshakeSecret []byte - masterSecret []byte - trafficSecret []byte // client_application_traffic_secret_0 - transcript hash.Hash - clientFinished []byte -} - -func (hs *serverHandshakeStateTLS13) handshake() error { - c := hs.c - - // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2. - if err := hs.processClientHello(); err != nil { - return err - } - if err := hs.checkForResumption(); err != nil { - return err - } - if err := hs.pickCertificate(); err != nil { - return err - } - c.buffering = true - if err := hs.sendServerParameters(); err != nil { - return err - } - if err := hs.sendServerCertificate(); err != nil { - return err - } - if err := hs.sendServerFinished(); err != nil { - return err - } - // Note that at this point we could start sending application data without - // waiting for the client's second flight, but the application might not - // expect the lack of replay protection of the ClientHello parameters. - if _, err := c.flush(); err != nil { - return err - } - if err := hs.readClientCertificate(); err != nil { - return err - } - if err := hs.readClientFinished(); err != nil { - return err - } - - atomic.StoreUint32(&c.handshakeStatus, 1) - - return nil -} - -func (hs *serverHandshakeStateTLS13) processClientHello() error { - c := hs.c - - hs.hello = new(serverHelloMsg) - hs.encryptedExtensions = new(encryptedExtensionsMsg) - - // TLS 1.3 froze the ServerHello.legacy_version field, and uses - // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1. - hs.hello.vers = VersionTLS12 - hs.hello.supportedVersion = c.vers - - if len(hs.clientHello.supportedVersions) == 0 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client used the legacy version field to negotiate TLS 1.3") - } - - // Abort if the client is doing a fallback and landing lower than what we - // support. See RFC 7507, which however does not specify the interaction - // with supported_versions. The only difference is that with - // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4] - // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case, - // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to - // TLS 1.2, because a TLS 1.3 server would abort here. The situation before - // supported_versions was not better because there was just no way to do a - // TLS 1.4 handshake without risking the server selecting TLS 1.3. - for _, id := range hs.clientHello.cipherSuites { - if id == TLS_FALLBACK_SCSV { - // Use c.vers instead of max(supported_versions) because an attacker - // could defeat this by adding an arbitrary high version otherwise. - if c.vers < c.config.maxSupportedVersion() { - c.sendAlert(alertInappropriateFallback) - return errors.New("tls: client using inappropriate protocol fallback") - } - break - } - } - - if len(hs.clientHello.compressionMethods) != 1 || - hs.clientHello.compressionMethods[0] != compressionNone { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: TLS 1.3 client supports illegal compression methods") - } - - hs.hello.random = make([]byte, 32) - if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil { - c.sendAlert(alertInternalError) - return err - } - - if len(hs.clientHello.secureRenegotiation) != 0 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: initial handshake had non-empty renegotiation extension") - } - - hs.hello.sessionId = hs.clientHello.sessionId - hs.hello.compressionMethod = compressionNone - - if hs.suite == nil { - var preferenceList []uint16 - for _, suiteID := range c.config.CipherSuites { - for _, suite := range cipherSuitesTLS13 { - if suite.id == suiteID { - preferenceList = append(preferenceList, suiteID) - break - } - } - } - if len(preferenceList) == 0 { - preferenceList = defaultCipherSuitesTLS13 - if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) { - preferenceList = defaultCipherSuitesTLS13NoAES - } - } - for _, suiteID := range preferenceList { - hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID) - if hs.suite != nil { - break - } - } - } - if hs.suite == nil { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: no cipher suite supported by both client and server") - } - c.cipherSuite = hs.suite.id - hs.hello.cipherSuite = hs.suite.id - hs.transcript = hs.suite.hash.New() - - // Pick the ECDHE group in server preference order, but give priority to - // groups with a key share, to avoid a HelloRetryRequest round-trip. - var selectedGroup CurveID - var clientKeyShare *keyShare -GroupSelection: - for _, preferredGroup := range c.config.curvePreferences() { - for _, ks := range hs.clientHello.keyShares { - if ks.group == preferredGroup { - selectedGroup = ks.group - clientKeyShare = &ks - break GroupSelection - } - } - if selectedGroup != 0 { - continue - } - for _, group := range hs.clientHello.supportedCurves { - if group == preferredGroup { - selectedGroup = group - break - } - } - } - if selectedGroup == 0 { - c.sendAlert(alertHandshakeFailure) - return errors.New("tls: no ECDHE curve supported by both client and server") - } - if clientKeyShare == nil { - if err := hs.doHelloRetryRequest(selectedGroup); err != nil { - return err - } - clientKeyShare = &hs.clientHello.keyShares[0] - } - - if _, ok := curveForCurveID(selectedGroup); selectedGroup != X25519 && !ok { - c.sendAlert(alertInternalError) - return errors.New("tls: CurvePreferences includes unsupported curve") - } - params, err := generateECDHEParameters(c.config.rand(), selectedGroup) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()} - hs.sharedKey = params.SharedKey(clientKeyShare.data) - if hs.sharedKey == nil { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid client key share") - } - - c.serverName = hs.clientHello.serverName - - if c.extraConfig != nil && c.extraConfig.ReceivedExtensions != nil { - c.extraConfig.ReceivedExtensions(typeClientHello, hs.clientHello.additionalExtensions) - } - - selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols) - if err != nil { - hs.alpnNegotiationErr = err - } - hs.encryptedExtensions.alpnProtocol = selectedProto - c.clientProtocol = selectedProto - - return nil -} - -func (hs *serverHandshakeStateTLS13) checkForResumption() error { - c := hs.c - - if c.config.SessionTicketsDisabled { - return nil - } - - modeOK := false - for _, mode := range hs.clientHello.pskModes { - if mode == pskModeDHE { - modeOK = true - break - } - } - if !modeOK { - return nil - } - - if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: invalid or missing PSK binders") - } - if len(hs.clientHello.pskIdentities) == 0 { - return nil - } - - for i, identity := range hs.clientHello.pskIdentities { - if i >= maxClientPSKIdentities { - break - } - - plaintext, _ := c.decryptTicket(identity.label) - if plaintext == nil { - continue - } - sessionState := new(sessionStateTLS13) - if ok := sessionState.unmarshal(plaintext); !ok { - continue - } - - if hs.clientHello.earlyData { - if sessionState.maxEarlyData == 0 { - c.sendAlert(alertUnsupportedExtension) - return errors.New("tls: client sent unexpected early data") - } - - if hs.alpnNegotiationErr == nil && sessionState.alpn == c.clientProtocol && - c.extraConfig != nil && c.extraConfig.MaxEarlyData > 0 && - c.extraConfig.Accept0RTT != nil && c.extraConfig.Accept0RTT(sessionState.appData) { - hs.encryptedExtensions.earlyData = true - c.used0RTT = true - } - } - - createdAt := time.Unix(int64(sessionState.createdAt), 0) - if c.config.time().Sub(createdAt) > maxSessionTicketLifetime { - continue - } - - // We don't check the obfuscated ticket age because it's affected by - // clock skew and it's only a freshness signal useful for shrinking the - // window for replay attacks, which don't affect us as we don't do 0-RTT. - - pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite) - if pskSuite == nil || pskSuite.hash != hs.suite.hash { - continue - } - - // PSK connections don't re-establish client certificates, but carry - // them over in the session ticket. Ensure the presence of client certs - // in the ticket is consistent with the configured requirements. - sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0 - needClientCerts := requiresClientCert(c.config.ClientAuth) - if needClientCerts && !sessionHasClientCerts { - continue - } - if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { - continue - } - - psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption", - nil, hs.suite.hash.Size()) - hs.earlySecret = hs.suite.extract(psk, nil) - binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil) - // Clone the transcript in case a HelloRetryRequest was recorded. - transcript := cloneHash(hs.transcript, hs.suite.hash) - if transcript == nil { - c.sendAlert(alertInternalError) - return errors.New("tls: internal error: failed to clone hash") - } - transcript.Write(hs.clientHello.marshalWithoutBinders()) - pskBinder := hs.suite.finishedHash(binderKey, transcript) - if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid PSK binder") - } - - c.didResume = true - if err := c.processCertsFromClient(sessionState.certificate); err != nil { - return err - } - - h := cloneHash(hs.transcript, hs.suite.hash) - h.Write(hs.clientHello.marshal()) - if hs.encryptedExtensions.earlyData { - clientEarlySecret := hs.suite.deriveSecret(hs.earlySecret, "c e traffic", h) - c.in.exportKey(Encryption0RTT, hs.suite, clientEarlySecret) - if err := c.config.writeKeyLog(keyLogLabelEarlyTraffic, hs.clientHello.random, clientEarlySecret); err != nil { - c.sendAlert(alertInternalError) - return err - } - } - - hs.hello.selectedIdentityPresent = true - hs.hello.selectedIdentity = uint16(i) - hs.usingPSK = true - return nil - } - - return nil -} - -// cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler -// interfaces implemented by standard library hashes to clone the state of in -// to a new instance of h. It returns nil if the operation fails. -func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash { - // Recreate the interface to avoid importing encoding. - type binaryMarshaler interface { - MarshalBinary() (data []byte, err error) - UnmarshalBinary(data []byte) error - } - marshaler, ok := in.(binaryMarshaler) - if !ok { - return nil - } - state, err := marshaler.MarshalBinary() - if err != nil { - return nil - } - out := h.New() - unmarshaler, ok := out.(binaryMarshaler) - if !ok { - return nil - } - if err := unmarshaler.UnmarshalBinary(state); err != nil { - return nil - } - return out -} - -func (hs *serverHandshakeStateTLS13) pickCertificate() error { - c := hs.c - - // Only one of PSK and certificates are used at a time. - if hs.usingPSK { - return nil - } - - // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3. - if len(hs.clientHello.supportedSignatureAlgorithms) == 0 { - return c.sendAlert(alertMissingExtension) - } - - certificate, err := c.config.getCertificate(newClientHelloInfo(hs.ctx, c, hs.clientHello)) - if err != nil { - if err == errNoCertificates { - c.sendAlert(alertUnrecognizedName) - } else { - c.sendAlert(alertInternalError) - } - return err - } - hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms) - if err != nil { - // getCertificate returned a certificate that is unsupported or - // incompatible with the client's signature algorithms. - c.sendAlert(alertHandshakeFailure) - return err - } - hs.cert = certificate - - return nil -} - -// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility -// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4. -func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error { - if hs.sentDummyCCS { - return nil - } - hs.sentDummyCCS = true - - _, err := hs.c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - return err -} - -func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error { - c := hs.c - - // The first ClientHello gets double-hashed into the transcript upon a - // HelloRetryRequest. See RFC 8446, Section 4.4.1. - hs.transcript.Write(hs.clientHello.marshal()) - chHash := hs.transcript.Sum(nil) - hs.transcript.Reset() - hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))}) - hs.transcript.Write(chHash) - - helloRetryRequest := &serverHelloMsg{ - vers: hs.hello.vers, - random: helloRetryRequestRandom, - sessionId: hs.hello.sessionId, - cipherSuite: hs.hello.cipherSuite, - compressionMethod: hs.hello.compressionMethod, - supportedVersion: hs.hello.supportedVersion, - selectedGroup: selectedGroup, - } - - hs.transcript.Write(helloRetryRequest.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal()); err != nil { - return err - } - - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - - clientHello, ok := msg.(*clientHelloMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(clientHello, msg) - } - - if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client sent invalid key share in second ClientHello") - } - - if clientHello.earlyData { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client indicated early data in second ClientHello") - } - - if illegalClientHelloChange(clientHello, hs.clientHello) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client illegally modified second ClientHello") - } - - if clientHello.earlyData { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client offered 0-RTT data in second ClientHello") - } - - hs.clientHello = clientHello - return nil -} - -// illegalClientHelloChange reports whether the two ClientHello messages are -// different, with the exception of the changes allowed before and after a -// HelloRetryRequest. See RFC 8446, Section 4.1.2. -func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool { - if len(ch.supportedVersions) != len(ch1.supportedVersions) || - len(ch.cipherSuites) != len(ch1.cipherSuites) || - len(ch.supportedCurves) != len(ch1.supportedCurves) || - len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) || - len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) || - len(ch.alpnProtocols) != len(ch1.alpnProtocols) { - return true - } - for i := range ch.supportedVersions { - if ch.supportedVersions[i] != ch1.supportedVersions[i] { - return true - } - } - for i := range ch.cipherSuites { - if ch.cipherSuites[i] != ch1.cipherSuites[i] { - return true - } - } - for i := range ch.supportedCurves { - if ch.supportedCurves[i] != ch1.supportedCurves[i] { - return true - } - } - for i := range ch.supportedSignatureAlgorithms { - if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] { - return true - } - } - for i := range ch.supportedSignatureAlgorithmsCert { - if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] { - return true - } - } - for i := range ch.alpnProtocols { - if ch.alpnProtocols[i] != ch1.alpnProtocols[i] { - return true - } - } - return ch.vers != ch1.vers || - !bytes.Equal(ch.random, ch1.random) || - !bytes.Equal(ch.sessionId, ch1.sessionId) || - !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) || - ch.serverName != ch1.serverName || - ch.ocspStapling != ch1.ocspStapling || - !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) || - ch.ticketSupported != ch1.ticketSupported || - !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) || - ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported || - !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) || - ch.scts != ch1.scts || - !bytes.Equal(ch.cookie, ch1.cookie) || - !bytes.Equal(ch.pskModes, ch1.pskModes) -} - -func (hs *serverHandshakeStateTLS13) sendServerParameters() error { - c := hs.c - - hs.transcript.Write(hs.clientHello.marshal()) - hs.transcript.Write(hs.hello.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.hello.marshal()); err != nil { - return err - } - - if err := hs.sendDummyChangeCipherSpec(); err != nil { - return err - } - - earlySecret := hs.earlySecret - if earlySecret == nil { - earlySecret = hs.suite.extract(nil, nil) - } - hs.handshakeSecret = hs.suite.extract(hs.sharedKey, - hs.suite.deriveSecret(earlySecret, "derived", nil)) - - clientSecret := hs.suite.deriveSecret(hs.handshakeSecret, - clientHandshakeTrafficLabel, hs.transcript) - c.in.exportKey(EncryptionHandshake, hs.suite, clientSecret) - c.in.setTrafficSecret(hs.suite, clientSecret) - serverSecret := hs.suite.deriveSecret(hs.handshakeSecret, - serverHandshakeTrafficLabel, hs.transcript) - c.out.exportKey(EncryptionHandshake, hs.suite, serverSecret) - c.out.setTrafficSecret(hs.suite, serverSecret) - - err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - if hs.alpnNegotiationErr != nil { - c.sendAlert(alertNoApplicationProtocol) - return hs.alpnNegotiationErr - } - if hs.c.extraConfig != nil && hs.c.extraConfig.GetExtensions != nil { - hs.encryptedExtensions.additionalExtensions = hs.c.extraConfig.GetExtensions(typeEncryptedExtensions) - } - - hs.transcript.Write(hs.encryptedExtensions.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, hs.encryptedExtensions.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) requestClientCert() bool { - return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK -} - -func (hs *serverHandshakeStateTLS13) sendServerCertificate() error { - c := hs.c - - // Only one of PSK and certificates are used at a time. - if hs.usingPSK { - return nil - } - - if hs.requestClientCert() { - // Request a client certificate - certReq := new(certificateRequestMsgTLS13) - certReq.ocspStapling = true - certReq.scts = true - certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms - if c.config.ClientCAs != nil { - certReq.certificateAuthorities = c.config.ClientCAs.Subjects() - } - - hs.transcript.Write(certReq.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certReq.marshal()); err != nil { - return err - } - } - - certMsg := new(certificateMsgTLS13) - - certMsg.certificate = *hs.cert - certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0 - certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 - - hs.transcript.Write(certMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certMsg.marshal()); err != nil { - return err - } - - certVerifyMsg := new(certificateVerifyMsg) - certVerifyMsg.hasSignatureAlgorithm = true - certVerifyMsg.signatureAlgorithm = hs.sigAlg - - sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg) - if err != nil { - return c.sendAlert(alertInternalError) - } - - signed := signedMessage(sigHash, serverSignatureContext, hs.transcript) - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts) - if err != nil { - public := hs.cert.PrivateKey.(crypto.Signer).Public() - if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS && - rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS - c.sendAlert(alertHandshakeFailure) - } else { - c.sendAlert(alertInternalError) - } - return errors.New("tls: failed to sign handshake: " + err.Error()) - } - certVerifyMsg.signature = sig - - hs.transcript.Write(certVerifyMsg.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, certVerifyMsg.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) sendServerFinished() error { - c := hs.c - - finished := &finishedMsg{ - verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript), - } - - hs.transcript.Write(finished.marshal()) - if _, err := c.writeRecord(recordTypeHandshake, finished.marshal()); err != nil { - return err - } - - // Derive secrets that take context through the server Finished. - - hs.masterSecret = hs.suite.extract(nil, - hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil)) - - hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret, - clientApplicationTrafficLabel, hs.transcript) - serverSecret := hs.suite.deriveSecret(hs.masterSecret, - serverApplicationTrafficLabel, hs.transcript) - c.out.exportKey(EncryptionApplication, hs.suite, serverSecret) - c.out.setTrafficSecret(hs.suite, serverSecret) - - err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - - c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript) - - // If we did not request client certificates, at this point we can - // precompute the client finished and roll the transcript forward to send - // session tickets in our first flight. - if !hs.requestClientCert() { - if err := hs.sendSessionTickets(); err != nil { - return err - } - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool { - if hs.c.config.SessionTicketsDisabled { - return false - } - - // Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9. - for _, pskMode := range hs.clientHello.pskModes { - if pskMode == pskModeDHE { - return true - } - } - return false -} - -func (hs *serverHandshakeStateTLS13) sendSessionTickets() error { - c := hs.c - - hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript) - finishedMsg := &finishedMsg{ - verifyData: hs.clientFinished, - } - hs.transcript.Write(finishedMsg.marshal()) - - if !hs.shouldSendSessionTickets() { - return nil - } - - c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret, - resumptionLabel, hs.transcript) - - // Don't send session tickets when the alternative record layer is set. - // Instead, save the resumption secret on the Conn. - // Session tickets can then be generated by calling Conn.GetSessionTicket(). - if hs.c.extraConfig != nil && hs.c.extraConfig.AlternativeRecordLayer != nil { - return nil - } - - m, err := hs.c.getSessionTicketMsg(nil) - if err != nil { - return err - } - - if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) readClientCertificate() error { - c := hs.c - - if !hs.requestClientCert() { - // Make sure the connection is still being verified whether or not - // the server requested a client certificate. - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - return nil - } - - // If we requested a client certificate, then the client must send a - // certificate message. If it's empty, no CertificateVerify is sent. - - msg, err := c.readHandshake() - if err != nil { - return err - } - - certMsg, ok := msg.(*certificateMsgTLS13) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certMsg, msg) - } - hs.transcript.Write(certMsg.marshal()) - - if err := c.processCertsFromClient(certMsg.certificate); err != nil { - return err - } - - if c.config.VerifyConnection != nil { - if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - if len(certMsg.certificate.Certificate) != 0 { - msg, err = c.readHandshake() - if err != nil { - return err - } - - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(certVerify, msg) - } - - // See RFC 8446, Section 4.4.3. - if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms) { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client certificate used with invalid signature algorithm") - } - sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm) - if err != nil { - return c.sendAlert(alertInternalError) - } - if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 { - c.sendAlert(alertIllegalParameter) - return errors.New("tls: client certificate used with invalid signature algorithm") - } - signed := signedMessage(sigHash, clientSignatureContext, hs.transcript) - if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey, - sigHash, signed, certVerify.signature); err != nil { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid signature by the client certificate: " + err.Error()) - } - - hs.transcript.Write(certVerify.marshal()) - } - - // If we waited until the client certificates to send session tickets, we - // are ready to do it now. - if err := hs.sendSessionTickets(); err != nil { - return err - } - - return nil -} - -func (hs *serverHandshakeStateTLS13) readClientFinished() error { - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return err - } - - finished, ok := msg.(*finishedMsg) - if !ok { - c.sendAlert(alertUnexpectedMessage) - return unexpectedMessageError(finished, msg) - } - - if !hmac.Equal(hs.clientFinished, finished.verifyData) { - c.sendAlert(alertDecryptError) - return errors.New("tls: invalid client finished hash") - } - - c.in.exportKey(EncryptionApplication, hs.suite, hs.trafficSecret) - c.in.setTrafficSecret(hs.suite, hs.trafficSecret) - - return nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/key_agreement.go b/vendor/github.com/marten-seemann/qtls-go1-17/key_agreement.go deleted file mode 100644 index 453a8dcf0..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/key_agreement.go +++ /dev/null @@ -1,357 +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 qtls - -import ( - "crypto" - "crypto/md5" - "crypto/rsa" - "crypto/sha1" - "crypto/x509" - "errors" - "fmt" - "io" -) - -// a keyAgreement implements the client and server side of a TLS key agreement -// protocol by generating and processing key exchange messages. -type keyAgreement interface { - // On the server side, the first two methods are called in order. - - // In the case that the key agreement protocol doesn't use a - // ServerKeyExchange message, generateServerKeyExchange can return nil, - // nil. - generateServerKeyExchange(*config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) - processClientKeyExchange(*config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) - - // On the client side, the next two methods are called in order. - - // This method may not be called if the server doesn't send a - // ServerKeyExchange message. - processServerKeyExchange(*config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error - generateClientKeyExchange(*config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) -} - -var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message") -var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message") - -// rsaKeyAgreement implements the standard TLS key agreement where the client -// encrypts the pre-master secret to the server's public key. -type rsaKeyAgreement struct{} - -func (ka rsaKeyAgreement) generateServerKeyExchange(config *config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - return nil, nil -} - -func (ka rsaKeyAgreement) processClientKeyExchange(config *config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - if len(ckx.ciphertext) < 2 { - return nil, errClientKeyExchange - } - ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) - if ciphertextLen != len(ckx.ciphertext)-2 { - return nil, errClientKeyExchange - } - ciphertext := ckx.ciphertext[2:] - - priv, ok := cert.PrivateKey.(crypto.Decrypter) - if !ok { - return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter") - } - // Perform constant time RSA PKCS #1 v1.5 decryption - preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48}) - if err != nil { - return nil, err - } - // We don't check the version number in the premaster secret. For one, - // by checking it, we would leak information about the validity of the - // encrypted pre-master secret. Secondly, it provides only a small - // benefit against a downgrade attack and some implementations send the - // wrong version anyway. See the discussion at the end of section - // 7.4.7.1 of RFC 4346. - return preMasterSecret, nil -} - -func (ka rsaKeyAgreement) processServerKeyExchange(config *config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - return errors.New("tls: unexpected ServerKeyExchange") -} - -func (ka rsaKeyAgreement) generateClientKeyExchange(config *config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - preMasterSecret := make([]byte, 48) - preMasterSecret[0] = byte(clientHello.vers >> 8) - preMasterSecret[1] = byte(clientHello.vers) - _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) - if err != nil { - return nil, nil, err - } - - rsaKey, ok := cert.PublicKey.(*rsa.PublicKey) - if !ok { - return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite") - } - encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret) - if err != nil { - return nil, nil, err - } - ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, len(encrypted)+2) - ckx.ciphertext[0] = byte(len(encrypted) >> 8) - ckx.ciphertext[1] = byte(len(encrypted)) - copy(ckx.ciphertext[2:], encrypted) - return preMasterSecret, ckx, nil -} - -// sha1Hash calculates a SHA1 hash over the given byte slices. -func sha1Hash(slices [][]byte) []byte { - hsha1 := sha1.New() - for _, slice := range slices { - hsha1.Write(slice) - } - return hsha1.Sum(nil) -} - -// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the -// concatenation of an MD5 and SHA1 hash. -func md5SHA1Hash(slices [][]byte) []byte { - md5sha1 := make([]byte, md5.Size+sha1.Size) - hmd5 := md5.New() - for _, slice := range slices { - hmd5.Write(slice) - } - copy(md5sha1, hmd5.Sum(nil)) - copy(md5sha1[md5.Size:], sha1Hash(slices)) - return md5sha1 -} - -// hashForServerKeyExchange hashes the given slices and returns their digest -// using the given hash function (for >= TLS 1.2) or using a default based on -// the sigType (for earlier TLS versions). For Ed25519 signatures, which don't -// do pre-hashing, it returns the concatenation of the slices. -func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte { - if sigType == signatureEd25519 { - var signed []byte - for _, slice := range slices { - signed = append(signed, slice...) - } - return signed - } - if version >= VersionTLS12 { - h := hashFunc.New() - for _, slice := range slices { - h.Write(slice) - } - digest := h.Sum(nil) - return digest - } - if sigType == signatureECDSA { - return sha1Hash(slices) - } - return md5SHA1Hash(slices) -} - -// ecdheKeyAgreement implements a TLS key agreement where the server -// generates an ephemeral EC public/private key pair and signs it. The -// pre-master secret is then calculated using ECDH. The signature may -// be ECDSA, Ed25519 or RSA. -type ecdheKeyAgreement struct { - version uint16 - isRSA bool - params ecdheParameters - - // ckx and preMasterSecret are generated in processServerKeyExchange - // and returned in generateClientKeyExchange. - ckx *clientKeyExchangeMsg - preMasterSecret []byte -} - -func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - var curveID CurveID - for _, c := range clientHello.supportedCurves { - if config.supportsCurve(c) { - curveID = c - break - } - } - - if curveID == 0 { - return nil, errors.New("tls: no supported elliptic curves offered") - } - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - return nil, errors.New("tls: CurvePreferences includes unsupported curve") - } - - params, err := generateECDHEParameters(config.rand(), curveID) - if err != nil { - return nil, err - } - ka.params = params - - // See RFC 4492, Section 5.4. - ecdhePublic := params.PublicKey() - serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic)) - serverECDHEParams[0] = 3 // named curve - serverECDHEParams[1] = byte(curveID >> 8) - serverECDHEParams[2] = byte(curveID) - serverECDHEParams[3] = byte(len(ecdhePublic)) - copy(serverECDHEParams[4:], ecdhePublic) - - priv, ok := cert.PrivateKey.(crypto.Signer) - if !ok { - return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey) - } - - var signatureAlgorithm SignatureScheme - var sigType uint8 - var sigHash crypto.Hash - if ka.version >= VersionTLS12 { - signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms) - if err != nil { - return nil, err - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) - if err != nil { - return nil, err - } - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public()) - if err != nil { - return nil, err - } - } - if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { - return nil, errors.New("tls: certificate cannot be used with the selected cipher suite") - } - - signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams) - - signOpts := crypto.SignerOpts(sigHash) - if sigType == signatureRSAPSS { - signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash} - } - sig, err := priv.Sign(config.rand(), signed, signOpts) - if err != nil { - return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error()) - } - - skx := new(serverKeyExchangeMsg) - sigAndHashLen := 0 - if ka.version >= VersionTLS12 { - sigAndHashLen = 2 - } - skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig)) - copy(skx.key, serverECDHEParams) - k := skx.key[len(serverECDHEParams):] - if ka.version >= VersionTLS12 { - k[0] = byte(signatureAlgorithm >> 8) - k[1] = byte(signatureAlgorithm) - k = k[2:] - } - k[0] = byte(len(sig) >> 8) - k[1] = byte(len(sig)) - copy(k[2:], sig) - - return skx, nil -} - -func (ka *ecdheKeyAgreement) processClientKeyExchange(config *config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { - return nil, errClientKeyExchange - } - - preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:]) - if preMasterSecret == nil { - return nil, errClientKeyExchange - } - - return preMasterSecret, nil -} - -func (ka *ecdheKeyAgreement) processServerKeyExchange(config *config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - if len(skx.key) < 4 { - return errServerKeyExchange - } - if skx.key[0] != 3 { // named curve - return errors.New("tls: server selected unsupported curve") - } - curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2]) - - publicLen := int(skx.key[3]) - if publicLen+4 > len(skx.key) { - return errServerKeyExchange - } - serverECDHEParams := skx.key[:4+publicLen] - publicKey := serverECDHEParams[4:] - - sig := skx.key[4+publicLen:] - if len(sig) < 2 { - return errServerKeyExchange - } - - if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok { - return errors.New("tls: server selected unsupported curve") - } - - params, err := generateECDHEParameters(config.rand(), curveID) - if err != nil { - return err - } - ka.params = params - - ka.preMasterSecret = params.SharedKey(publicKey) - if ka.preMasterSecret == nil { - return errServerKeyExchange - } - - ourPublicKey := params.PublicKey() - ka.ckx = new(clientKeyExchangeMsg) - ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey)) - ka.ckx.ciphertext[0] = byte(len(ourPublicKey)) - copy(ka.ckx.ciphertext[1:], ourPublicKey) - - var sigType uint8 - var sigHash crypto.Hash - if ka.version >= VersionTLS12 { - signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1]) - sig = sig[2:] - if len(sig) < 2 { - return errServerKeyExchange - } - - if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) { - return errors.New("tls: certificate used with invalid signature algorithm") - } - sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) - if err != nil { - return err - } - } else { - sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey) - if err != nil { - return err - } - } - if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { - return errServerKeyExchange - } - - sigLen := int(sig[0])<<8 | int(sig[1]) - if sigLen+2 != len(sig) { - return errServerKeyExchange - } - sig = sig[2:] - - signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams) - if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil { - return errors.New("tls: invalid signature by the server certificate: " + err.Error()) - } - return nil -} - -func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - if ka.ckx == nil { - return nil, nil, errors.New("tls: missing ServerKeyExchange message") - } - - return ka.preMasterSecret, ka.ckx, nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/key_schedule.go b/vendor/github.com/marten-seemann/qtls-go1-17/key_schedule.go deleted file mode 100644 index da13904a6..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/key_schedule.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package qtls - -import ( - "crypto/elliptic" - "crypto/hmac" - "errors" - "hash" - "io" - "math/big" - - "golang.org/x/crypto/cryptobyte" - "golang.org/x/crypto/curve25519" - "golang.org/x/crypto/hkdf" -) - -// This file contains the functions necessary to compute the TLS 1.3 key -// schedule. See RFC 8446, Section 7. - -const ( - resumptionBinderLabel = "res binder" - clientHandshakeTrafficLabel = "c hs traffic" - serverHandshakeTrafficLabel = "s hs traffic" - clientApplicationTrafficLabel = "c ap traffic" - serverApplicationTrafficLabel = "s ap traffic" - exporterLabel = "exp master" - resumptionLabel = "res master" - trafficUpdateLabel = "traffic upd" -) - -// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1. -func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte { - var hkdfLabel cryptobyte.Builder - hkdfLabel.AddUint16(uint16(length)) - hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte("tls13 ")) - b.AddBytes([]byte(label)) - }) - hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(context) - }) - out := make([]byte, length) - n, err := hkdf.Expand(c.hash.New, secret, hkdfLabel.BytesOrPanic()).Read(out) - if err != nil || n != length { - panic("tls: HKDF-Expand-Label invocation failed unexpectedly") - } - return out -} - -// deriveSecret implements Derive-Secret from RFC 8446, Section 7.1. -func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte { - if transcript == nil { - transcript = c.hash.New() - } - return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size()) -} - -// extract implements HKDF-Extract with the cipher suite hash. -func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte { - if newSecret == nil { - newSecret = make([]byte, c.hash.Size()) - } - return hkdf.Extract(c.hash.New, newSecret, currentSecret) -} - -// nextTrafficSecret generates the next traffic secret, given the current one, -// according to RFC 8446, Section 7.2. -func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte { - return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size()) -} - -// trafficKey generates traffic keys according to RFC 8446, Section 7.3. -func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) { - key = c.expandLabel(trafficSecret, "key", nil, c.keyLen) - iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength) - return -} - -// finishedHash generates the Finished verify_data or PskBinderEntry according -// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey -// selection. -func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte { - finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size()) - verifyData := hmac.New(c.hash.New, finishedKey) - verifyData.Write(transcript.Sum(nil)) - return verifyData.Sum(nil) -} - -// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to -// RFC 8446, Section 7.5. -func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) { - expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript) - return func(label string, context []byte, length int) ([]byte, error) { - secret := c.deriveSecret(expMasterSecret, label, nil) - h := c.hash.New() - h.Write(context) - return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil - } -} - -// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519, -// according to RFC 8446, Section 4.2.8.2. -type ecdheParameters interface { - CurveID() CurveID - PublicKey() []byte - SharedKey(peerPublicKey []byte) []byte -} - -func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) { - if curveID == X25519 { - privateKey := make([]byte, curve25519.ScalarSize) - if _, err := io.ReadFull(rand, privateKey); err != nil { - return nil, err - } - publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint) - if err != nil { - return nil, err - } - return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil - } - - curve, ok := curveForCurveID(curveID) - if !ok { - return nil, errors.New("tls: internal error: unsupported curve") - } - - p := &nistParameters{curveID: curveID} - var err error - p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand) - if err != nil { - return nil, err - } - return p, nil -} - -func curveForCurveID(id CurveID) (elliptic.Curve, bool) { - switch id { - case CurveP256: - return elliptic.P256(), true - case CurveP384: - return elliptic.P384(), true - case CurveP521: - return elliptic.P521(), true - default: - return nil, false - } -} - -type nistParameters struct { - privateKey []byte - x, y *big.Int // public key - curveID CurveID -} - -func (p *nistParameters) CurveID() CurveID { - return p.curveID -} - -func (p *nistParameters) PublicKey() []byte { - curve, _ := curveForCurveID(p.curveID) - return elliptic.Marshal(curve, p.x, p.y) -} - -func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte { - curve, _ := curveForCurveID(p.curveID) - // Unmarshal also checks whether the given point is on the curve. - x, y := elliptic.Unmarshal(curve, peerPublicKey) - if x == nil { - return nil - } - - xShared, _ := curve.ScalarMult(x, y, p.privateKey) - sharedKey := make([]byte, (curve.Params().BitSize+7)/8) - return xShared.FillBytes(sharedKey) -} - -type x25519Parameters struct { - privateKey []byte - publicKey []byte -} - -func (p *x25519Parameters) CurveID() CurveID { - return X25519 -} - -func (p *x25519Parameters) PublicKey() []byte { - return p.publicKey[:] -} - -func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte { - sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey) - if err != nil { - return nil - } - return sharedKey -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/prf.go b/vendor/github.com/marten-seemann/qtls-go1-17/prf.go deleted file mode 100644 index 9eb0221a0..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/prf.go +++ /dev/null @@ -1,283 +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 qtls - -import ( - "crypto" - "crypto/hmac" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "errors" - "fmt" - "hash" -) - -// Split a premaster secret in two as specified in RFC 4346, Section 5. -func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { - s1 = secret[0 : (len(secret)+1)/2] - s2 = secret[len(secret)/2:] - return -} - -// pHash implements the P_hash function, as defined in RFC 4346, Section 5. -func pHash(result, secret, seed []byte, hash func() hash.Hash) { - h := hmac.New(hash, secret) - h.Write(seed) - a := h.Sum(nil) - - j := 0 - for j < len(result) { - h.Reset() - h.Write(a) - h.Write(seed) - b := h.Sum(nil) - copy(result[j:], b) - j += len(b) - - h.Reset() - h.Write(a) - a = h.Sum(nil) - } -} - -// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5. -func prf10(result, secret, label, seed []byte) { - hashSHA1 := sha1.New - hashMD5 := md5.New - - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - s1, s2 := splitPreMasterSecret(secret) - pHash(result, s1, labelAndSeed, hashMD5) - result2 := make([]byte, len(result)) - pHash(result2, s2, labelAndSeed, hashSHA1) - - for i, b := range result2 { - result[i] ^= b - } -} - -// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5. -func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) { - return func(result, secret, label, seed []byte) { - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - pHash(result, secret, labelAndSeed, hashFunc) - } -} - -const ( - masterSecretLength = 48 // Length of a master secret in TLS 1.1. - finishedVerifyLength = 12 // Length of verify_data in a Finished message. -) - -var masterSecretLabel = []byte("master secret") -var keyExpansionLabel = []byte("key expansion") -var clientFinishedLabel = []byte("client finished") -var serverFinishedLabel = []byte("server finished") - -func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) { - switch version { - case VersionTLS10, VersionTLS11: - return prf10, crypto.Hash(0) - case VersionTLS12: - if suite.flags&suiteSHA384 != 0 { - return prf12(sha512.New384), crypto.SHA384 - } - return prf12(sha256.New), crypto.SHA256 - default: - panic("unknown version") - } -} - -func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) { - prf, _ := prfAndHashForVersion(version, suite) - return prf -} - -// masterFromPreMasterSecret generates the master secret from the pre-master -// secret. See RFC 5246, Section 8.1. -func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte { - seed := make([]byte, 0, len(clientRandom)+len(serverRandom)) - seed = append(seed, clientRandom...) - seed = append(seed, serverRandom...) - - masterSecret := make([]byte, masterSecretLength) - prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed) - return masterSecret -} - -// keysFromMasterSecret generates the connection keys from the master -// secret, given the lengths of the MAC key, cipher key and IV, as defined in -// RFC 2246, Section 6.3. -func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { - seed := make([]byte, 0, len(serverRandom)+len(clientRandom)) - seed = append(seed, serverRandom...) - seed = append(seed, clientRandom...) - - n := 2*macLen + 2*keyLen + 2*ivLen - keyMaterial := make([]byte, n) - prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed) - clientMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - serverMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - clientKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - serverKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - clientIV = keyMaterial[:ivLen] - keyMaterial = keyMaterial[ivLen:] - serverIV = keyMaterial[:ivLen] - return -} - -func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash { - var buffer []byte - if version >= VersionTLS12 { - buffer = []byte{} - } - - prf, hash := prfAndHashForVersion(version, cipherSuite) - if hash != 0 { - return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf} - } - - return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf} -} - -// A finishedHash calculates the hash of a set of handshake messages suitable -// for including in a Finished message. -type finishedHash struct { - client hash.Hash - server hash.Hash - - // Prior to TLS 1.2, an additional MD5 hash is required. - clientMD5 hash.Hash - serverMD5 hash.Hash - - // In TLS 1.2, a full buffer is sadly required. - buffer []byte - - version uint16 - prf func(result, secret, label, seed []byte) -} - -func (h *finishedHash) Write(msg []byte) (n int, err error) { - h.client.Write(msg) - h.server.Write(msg) - - if h.version < VersionTLS12 { - h.clientMD5.Write(msg) - h.serverMD5.Write(msg) - } - - if h.buffer != nil { - h.buffer = append(h.buffer, msg...) - } - - return len(msg), nil -} - -func (h finishedHash) Sum() []byte { - if h.version >= VersionTLS12 { - return h.client.Sum(nil) - } - - out := make([]byte, 0, md5.Size+sha1.Size) - out = h.clientMD5.Sum(out) - return h.client.Sum(out) -} - -// clientSum returns the contents of the verify_data member of a client's -// Finished message. -func (h finishedHash) clientSum(masterSecret []byte) []byte { - out := make([]byte, finishedVerifyLength) - h.prf(out, masterSecret, clientFinishedLabel, h.Sum()) - return out -} - -// serverSum returns the contents of the verify_data member of a server's -// Finished message. -func (h finishedHash) serverSum(masterSecret []byte) []byte { - out := make([]byte, finishedVerifyLength) - h.prf(out, masterSecret, serverFinishedLabel, h.Sum()) - return out -} - -// hashForClientCertificate returns the handshake messages so far, pre-hashed if -// necessary, suitable for signing by a TLS client certificate. -func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash, masterSecret []byte) []byte { - if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil { - panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer") - } - - if sigType == signatureEd25519 { - return h.buffer - } - - if h.version >= VersionTLS12 { - hash := hashAlg.New() - hash.Write(h.buffer) - return hash.Sum(nil) - } - - if sigType == signatureECDSA { - return h.server.Sum(nil) - } - - return h.Sum() -} - -// discardHandshakeBuffer is called when there is no more need to -// buffer the entirety of the handshake messages. -func (h *finishedHash) discardHandshakeBuffer() { - h.buffer = nil -} - -// noExportedKeyingMaterial is used as a value of -// ConnectionState.ekm when renegotiation is enabled and thus -// we wish to fail all key-material export requests. -func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) { - return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled") -} - -// ekmFromMasterSecret generates exported keying material as defined in RFC 5705. -func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) { - return func(label string, context []byte, length int) ([]byte, error) { - switch label { - case "client finished", "server finished", "master secret", "key expansion": - // These values are reserved and may not be used. - return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label) - } - - seedLen := len(serverRandom) + len(clientRandom) - if context != nil { - seedLen += 2 + len(context) - } - seed := make([]byte, 0, seedLen) - - seed = append(seed, clientRandom...) - seed = append(seed, serverRandom...) - - if context != nil { - if len(context) >= 1<<16 { - return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long") - } - seed = append(seed, byte(len(context)>>8), byte(len(context))) - seed = append(seed, context...) - } - - keyMaterial := make([]byte, length) - prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed) - return keyMaterial, nil - } -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/ticket.go b/vendor/github.com/marten-seemann/qtls-go1-17/ticket.go deleted file mode 100644 index 81e8a52ea..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/ticket.go +++ /dev/null @@ -1,274 +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 qtls - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/sha256" - "crypto/subtle" - "encoding/binary" - "errors" - "io" - "time" - - "golang.org/x/crypto/cryptobyte" -) - -// sessionState contains the information that is serialized into a session -// ticket in order to later resume a connection. -type sessionState struct { - vers uint16 - cipherSuite uint16 - createdAt uint64 - masterSecret []byte // opaque master_secret<1..2^16-1>; - // struct { opaque certificate<1..2^24-1> } Certificate; - certificates [][]byte // Certificate certificate_list<0..2^24-1>; - - // usedOldKey is true if the ticket from which this session came from - // was encrypted with an older key and thus should be refreshed. - usedOldKey bool -} - -func (m *sessionState) marshal() []byte { - var b cryptobyte.Builder - b.AddUint16(m.vers) - b.AddUint16(m.cipherSuite) - addUint64(&b, m.createdAt) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.masterSecret) - }) - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - for _, cert := range m.certificates { - b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(cert) - }) - } - }) - return b.BytesOrPanic() -} - -func (m *sessionState) unmarshal(data []byte) bool { - *m = sessionState{usedOldKey: m.usedOldKey} - s := cryptobyte.String(data) - if ok := s.ReadUint16(&m.vers) && - s.ReadUint16(&m.cipherSuite) && - readUint64(&s, &m.createdAt) && - readUint16LengthPrefixed(&s, &m.masterSecret) && - len(m.masterSecret) != 0; !ok { - return false - } - var certList cryptobyte.String - if !s.ReadUint24LengthPrefixed(&certList) { - return false - } - for !certList.Empty() { - var cert []byte - if !readUint24LengthPrefixed(&certList, &cert) { - return false - } - m.certificates = append(m.certificates, cert) - } - return s.Empty() -} - -// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first -// version (revision = 0) doesn't carry any of the information needed for 0-RTT -// validation and the nonce is always empty. -// version (revision = 1) carries the max_early_data_size sent in the ticket. -// version (revision = 2) carries the ALPN sent in the ticket. -type sessionStateTLS13 struct { - // uint8 version = 0x0304; - // uint8 revision = 2; - cipherSuite uint16 - createdAt uint64 - resumptionSecret []byte // opaque resumption_master_secret<1..2^8-1>; - certificate Certificate // CertificateEntry certificate_list<0..2^24-1>; - maxEarlyData uint32 - alpn string - - appData []byte -} - -func (m *sessionStateTLS13) marshal() []byte { - var b cryptobyte.Builder - b.AddUint16(VersionTLS13) - b.AddUint8(2) // revision - b.AddUint16(m.cipherSuite) - addUint64(&b, m.createdAt) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.resumptionSecret) - }) - marshalCertificate(&b, m.certificate) - b.AddUint32(m.maxEarlyData) - b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes([]byte(m.alpn)) - }) - b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { - b.AddBytes(m.appData) - }) - return b.BytesOrPanic() -} - -func (m *sessionStateTLS13) unmarshal(data []byte) bool { - *m = sessionStateTLS13{} - s := cryptobyte.String(data) - var version uint16 - var revision uint8 - var alpn []byte - ret := s.ReadUint16(&version) && - version == VersionTLS13 && - s.ReadUint8(&revision) && - revision == 2 && - s.ReadUint16(&m.cipherSuite) && - readUint64(&s, &m.createdAt) && - readUint8LengthPrefixed(&s, &m.resumptionSecret) && - len(m.resumptionSecret) != 0 && - unmarshalCertificate(&s, &m.certificate) && - s.ReadUint32(&m.maxEarlyData) && - readUint8LengthPrefixed(&s, &alpn) && - readUint16LengthPrefixed(&s, &m.appData) && - s.Empty() - m.alpn = string(alpn) - return ret -} - -func (c *Conn) encryptTicket(state []byte) ([]byte, error) { - if len(c.ticketKeys) == 0 { - return nil, errors.New("tls: internal error: session ticket keys unavailable") - } - - encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size) - keyName := encrypted[:ticketKeyNameLen] - iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - - if _, err := io.ReadFull(c.config.rand(), iv); err != nil { - return nil, err - } - key := c.ticketKeys[0] - copy(keyName, key.keyName[:]) - block, err := aes.NewCipher(key.aesKey[:]) - if err != nil { - return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) - } - cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state) - - mac := hmac.New(sha256.New, key.hmacKey[:]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - mac.Sum(macBytes[:0]) - - return encrypted, nil -} - -func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) { - if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size { - return nil, false - } - - keyName := encrypted[:ticketKeyNameLen] - iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size] - - keyIndex := -1 - for i, candidateKey := range c.ticketKeys { - if bytes.Equal(keyName, candidateKey.keyName[:]) { - keyIndex = i - break - } - } - if keyIndex == -1 { - return nil, false - } - key := &c.ticketKeys[keyIndex] - - mac := hmac.New(sha256.New, key.hmacKey[:]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - expected := mac.Sum(nil) - - if subtle.ConstantTimeCompare(macBytes, expected) != 1 { - return nil, false - } - - block, err := aes.NewCipher(key.aesKey[:]) - if err != nil { - return nil, false - } - plaintext = make([]byte, len(ciphertext)) - cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext) - - return plaintext, keyIndex > 0 -} - -func (c *Conn) getSessionTicketMsg(appData []byte) (*newSessionTicketMsgTLS13, error) { - m := new(newSessionTicketMsgTLS13) - - var certsFromClient [][]byte - for _, cert := range c.peerCertificates { - certsFromClient = append(certsFromClient, cert.Raw) - } - state := sessionStateTLS13{ - cipherSuite: c.cipherSuite, - createdAt: uint64(c.config.time().Unix()), - resumptionSecret: c.resumptionSecret, - certificate: Certificate{ - Certificate: certsFromClient, - OCSPStaple: c.ocspResponse, - SignedCertificateTimestamps: c.scts, - }, - appData: appData, - alpn: c.clientProtocol, - } - if c.extraConfig != nil { - state.maxEarlyData = c.extraConfig.MaxEarlyData - } - var err error - m.label, err = c.encryptTicket(state.marshal()) - if err != nil { - return nil, err - } - m.lifetime = uint32(maxSessionTicketLifetime / time.Second) - - // ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1 - // The value is not stored anywhere; we never need to check the ticket age - // because 0-RTT is not supported. - ageAdd := make([]byte, 4) - _, err = c.config.rand().Read(ageAdd) - if err != nil { - return nil, err - } - m.ageAdd = binary.LittleEndian.Uint32(ageAdd) - - // ticket_nonce, which must be unique per connection, is always left at - // zero because we only ever send one ticket per connection. - - if c.extraConfig != nil { - m.maxEarlyData = c.extraConfig.MaxEarlyData - } - return m, nil -} - -// GetSessionTicket generates a new session ticket. -// It should only be called after the handshake completes. -// It can only be used for servers, and only if the alternative record layer is set. -// The ticket may be nil if config.SessionTicketsDisabled is set, -// or if the client isn't able to receive session tickets. -func (c *Conn) GetSessionTicket(appData []byte) ([]byte, error) { - if c.isClient || !c.handshakeComplete() || c.extraConfig == nil || c.extraConfig.AlternativeRecordLayer == nil { - return nil, errors.New("GetSessionTicket is only valid for servers after completion of the handshake, and if an alternative record layer is set.") - } - if c.config.SessionTicketsDisabled { - return nil, nil - } - - m, err := c.getSessionTicketMsg(appData) - if err != nil { - return nil, err - } - return m.marshal(), nil -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/tls.go b/vendor/github.com/marten-seemann/qtls-go1-17/tls.go deleted file mode 100644 index 42207c235..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/tls.go +++ /dev/null @@ -1,362 +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 qtls partially implements TLS 1.2, as specified in RFC 5246, -// and TLS 1.3, as specified in RFC 8446. -package qtls - -// BUG(agl): The crypto/tls package only implements some countermeasures -// against Lucky13 attacks on CBC-mode encryption, and only on SHA1 -// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and -// https://www.imperialviolet.org/2013/02/04/luckythirteen.html. - -import ( - "bytes" - "context" - "crypto" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" - "fmt" - "net" - "os" - "strings" -) - -// Server returns a new TLS server side connection -// using conn as the underlying transport. -// The configuration config must be non-nil and must include -// at least one certificate or else set GetCertificate. -func Server(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - c := &Conn{ - conn: conn, - config: fromConfig(config), - extraConfig: extraConfig, - } - c.handshakeFn = c.serverHandshake - return c -} - -// Client returns a new TLS client side connection -// using conn as the underlying transport. -// The config cannot be nil: users must set either ServerName or -// InsecureSkipVerify in the config. -func Client(conn net.Conn, config *Config, extraConfig *ExtraConfig) *Conn { - c := &Conn{ - conn: conn, - config: fromConfig(config), - extraConfig: extraConfig, - isClient: true, - } - c.handshakeFn = c.clientHandshake - return c -} - -// A listener implements a network listener (net.Listener) for TLS connections. -type listener struct { - net.Listener - config *Config - extraConfig *ExtraConfig -} - -// Accept waits for and returns the next incoming TLS connection. -// The returned connection is of type *Conn. -func (l *listener) Accept() (net.Conn, error) { - c, err := l.Listener.Accept() - if err != nil { - return nil, err - } - return Server(c, l.config, l.extraConfig), nil -} - -// NewListener creates a Listener which accepts connections from an inner -// Listener and wraps each connection with Server. -// The configuration config must be non-nil and must include -// at least one certificate or else set GetCertificate. -func NewListener(inner net.Listener, config *Config, extraConfig *ExtraConfig) net.Listener { - l := new(listener) - l.Listener = inner - l.config = config - l.extraConfig = extraConfig - return l -} - -// Listen creates a TLS listener accepting connections on the -// given network address using net.Listen. -// The configuration config must be non-nil and must include -// at least one certificate or else set GetCertificate. -func Listen(network, laddr string, config *Config, extraConfig *ExtraConfig) (net.Listener, error) { - if config == nil || len(config.Certificates) == 0 && - config.GetCertificate == nil && config.GetConfigForClient == nil { - return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config") - } - l, err := net.Listen(network, laddr) - if err != nil { - return nil, err - } - return NewListener(l, config, extraConfig), nil -} - -type timeoutError struct{} - -func (timeoutError) Error() string { return "tls: DialWithDialer timed out" } -func (timeoutError) Timeout() bool { return true } -func (timeoutError) Temporary() bool { return true } - -// DialWithDialer connects to the given network address using dialer.Dial and -// then initiates a TLS handshake, returning the resulting TLS connection. Any -// timeout or deadline given in the dialer apply to connection and TLS -// handshake as a whole. -// -// DialWithDialer interprets a nil configuration as equivalent to the zero -// configuration; see the documentation of Config for the defaults. -// -// DialWithDialer uses context.Background internally; to specify the context, -// use Dialer.DialContext with NetDialer set to the desired dialer. -func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) { - return dial(context.Background(), dialer, network, addr, config, extraConfig) -} - -func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) { - if netDialer.Timeout != 0 { - var cancel context.CancelFunc - ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout) - defer cancel() - } - - if !netDialer.Deadline.IsZero() { - var cancel context.CancelFunc - ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline) - defer cancel() - } - - rawConn, err := netDialer.DialContext(ctx, network, addr) - if err != nil { - return nil, err - } - - colonPos := strings.LastIndex(addr, ":") - if colonPos == -1 { - colonPos = len(addr) - } - hostname := addr[:colonPos] - - if config == nil { - config = defaultConfig() - } - // If no ServerName is set, infer the ServerName - // from the hostname we're connecting to. - if config.ServerName == "" { - // Make a copy to avoid polluting argument or default. - c := config.Clone() - c.ServerName = hostname - config = c - } - - conn := Client(rawConn, config, extraConfig) - if err := conn.HandshakeContext(ctx); err != nil { - rawConn.Close() - return nil, err - } - return conn, nil -} - -// Dial connects to the given network address using net.Dial -// and then initiates a TLS handshake, returning the resulting -// TLS connection. -// Dial interprets a nil configuration as equivalent to -// the zero configuration; see the documentation of Config -// for the defaults. -func Dial(network, addr string, config *Config, extraConfig *ExtraConfig) (*Conn, error) { - return DialWithDialer(new(net.Dialer), network, addr, config, extraConfig) -} - -// Dialer dials TLS connections given a configuration and a Dialer for the -// underlying connection. -type Dialer struct { - // NetDialer is the optional dialer to use for the TLS connections' - // underlying TCP connections. - // A nil NetDialer is equivalent to the net.Dialer zero value. - NetDialer *net.Dialer - - // Config is the TLS configuration to use for new connections. - // A nil configuration is equivalent to the zero - // configuration; see the documentation of Config for the - // defaults. - Config *Config - - ExtraConfig *ExtraConfig -} - -// Dial connects to the given network address and initiates a TLS -// handshake, returning the resulting TLS connection. -// -// The returned Conn, if any, will always be of type *Conn. -// -// Dial uses context.Background internally; to specify the context, -// use DialContext. -func (d *Dialer) Dial(network, addr string) (net.Conn, error) { - return d.DialContext(context.Background(), network, addr) -} - -func (d *Dialer) netDialer() *net.Dialer { - if d.NetDialer != nil { - return d.NetDialer - } - return new(net.Dialer) -} - -// DialContext connects to the given network address and initiates a TLS -// handshake, returning the resulting TLS connection. -// -// The provided Context must be non-nil. If the context expires before -// the connection is complete, an error is returned. Once successfully -// connected, any expiration of the context will not affect the -// connection. -// -// The returned Conn, if any, will always be of type *Conn. -func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) { - c, err := dial(ctx, d.netDialer(), network, addr, d.Config, d.ExtraConfig) - if err != nil { - // Don't return c (a typed nil) in an interface. - return nil, err - } - return c, nil -} - -// LoadX509KeyPair reads and parses a public/private key pair from a pair -// of files. The files must contain PEM encoded data. The certificate file -// may contain intermediate certificates following the leaf certificate to -// form a certificate chain. On successful return, Certificate.Leaf will -// be nil because the parsed form of the certificate is not retained. -func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) { - certPEMBlock, err := os.ReadFile(certFile) - if err != nil { - return Certificate{}, err - } - keyPEMBlock, err := os.ReadFile(keyFile) - if err != nil { - return Certificate{}, err - } - return X509KeyPair(certPEMBlock, keyPEMBlock) -} - -// X509KeyPair parses a public/private key pair from a pair of -// PEM encoded data. On successful return, Certificate.Leaf will be nil because -// the parsed form of the certificate is not retained. -func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { - fail := func(err error) (Certificate, error) { return Certificate{}, err } - - var cert Certificate - var skippedBlockTypes []string - for { - var certDERBlock *pem.Block - certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) - if certDERBlock == nil { - break - } - if certDERBlock.Type == "CERTIFICATE" { - cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) - } else { - skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type) - } - } - - if len(cert.Certificate) == 0 { - if len(skippedBlockTypes) == 0 { - return fail(errors.New("tls: failed to find any PEM data in certificate input")) - } - if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") { - return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched")) - } - return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) - } - - skippedBlockTypes = skippedBlockTypes[:0] - var keyDERBlock *pem.Block - for { - keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) - if keyDERBlock == nil { - if len(skippedBlockTypes) == 0 { - return fail(errors.New("tls: failed to find any PEM data in key input")) - } - if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" { - return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key")) - } - return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes)) - } - if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { - break - } - skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type) - } - - // We don't need to parse the public key for TLS, but we so do anyway - // to check that it looks sane and matches the private key. - x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - return fail(err) - } - - cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) - if err != nil { - return fail(err) - } - - switch pub := x509Cert.PublicKey.(type) { - case *rsa.PublicKey: - priv, ok := cert.PrivateKey.(*rsa.PrivateKey) - if !ok { - return fail(errors.New("tls: private key type does not match public key type")) - } - if pub.N.Cmp(priv.N) != 0 { - return fail(errors.New("tls: private key does not match public key")) - } - case *ecdsa.PublicKey: - priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) - if !ok { - return fail(errors.New("tls: private key type does not match public key type")) - } - if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { - return fail(errors.New("tls: private key does not match public key")) - } - case ed25519.PublicKey: - priv, ok := cert.PrivateKey.(ed25519.PrivateKey) - if !ok { - return fail(errors.New("tls: private key type does not match public key type")) - } - if !bytes.Equal(priv.Public().(ed25519.PublicKey), pub) { - return fail(errors.New("tls: private key does not match public key")) - } - default: - return fail(errors.New("tls: unknown public key algorithm")) - } - - return cert, nil -} - -// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates -// PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys. -// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. -func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { - if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { - return key, nil - } - if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { - switch key := key.(type) { - case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey: - return key, nil - default: - return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping") - } - } - if key, err := x509.ParseECPrivateKey(der); err == nil { - return key, nil - } - - return nil, errors.New("tls: failed to parse private key") -} diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/unsafe.go b/vendor/github.com/marten-seemann/qtls-go1-17/unsafe.go deleted file mode 100644 index 55fa01b3d..000000000 --- a/vendor/github.com/marten-seemann/qtls-go1-17/unsafe.go +++ /dev/null @@ -1,96 +0,0 @@ -package qtls - -import ( - "crypto/tls" - "reflect" - "unsafe" -) - -func init() { - if !structsEqual(&tls.ConnectionState{}, &connectionState{}) { - panic("qtls.ConnectionState doesn't match") - } - if !structsEqual(&tls.ClientSessionState{}, &clientSessionState{}) { - panic("qtls.ClientSessionState doesn't match") - } - if !structsEqual(&tls.CertificateRequestInfo{}, &certificateRequestInfo{}) { - panic("qtls.CertificateRequestInfo doesn't match") - } - if !structsEqual(&tls.Config{}, &config{}) { - panic("qtls.Config doesn't match") - } - if !structsEqual(&tls.ClientHelloInfo{}, &clientHelloInfo{}) { - panic("qtls.ClientHelloInfo doesn't match") - } -} - -func toConnectionState(c connectionState) ConnectionState { - return *(*ConnectionState)(unsafe.Pointer(&c)) -} - -func toClientSessionState(s *clientSessionState) *ClientSessionState { - return (*ClientSessionState)(unsafe.Pointer(s)) -} - -func fromClientSessionState(s *ClientSessionState) *clientSessionState { - return (*clientSessionState)(unsafe.Pointer(s)) -} - -func toCertificateRequestInfo(i *certificateRequestInfo) *CertificateRequestInfo { - return (*CertificateRequestInfo)(unsafe.Pointer(i)) -} - -func toConfig(c *config) *Config { - return (*Config)(unsafe.Pointer(c)) -} - -func fromConfig(c *Config) *config { - return (*config)(unsafe.Pointer(c)) -} - -func toClientHelloInfo(chi *clientHelloInfo) *ClientHelloInfo { - return (*ClientHelloInfo)(unsafe.Pointer(chi)) -} - -func structsEqual(a, b interface{}) bool { - return compare(reflect.ValueOf(a), reflect.ValueOf(b)) -} - -func compare(a, b reflect.Value) bool { - sa := a.Elem() - sb := b.Elem() - if sa.NumField() != sb.NumField() { - return false - } - for i := 0; i < sa.NumField(); i++ { - fa := sa.Type().Field(i) - fb := sb.Type().Field(i) - if !reflect.DeepEqual(fa.Index, fb.Index) || fa.Name != fb.Name || fa.Anonymous != fb.Anonymous || fa.Offset != fb.Offset || !reflect.DeepEqual(fa.Type, fb.Type) { - if fa.Type.Kind() != fb.Type.Kind() { - return false - } - if fa.Type.Kind() == reflect.Slice { - if !compareStruct(fa.Type.Elem(), fb.Type.Elem()) { - return false - } - continue - } - return false - } - } - return true -} - -func compareStruct(a, b reflect.Type) bool { - if a.NumField() != b.NumField() { - return false - } - for i := 0; i < a.NumField(); i++ { - fa := a.Field(i) - fb := b.Field(i) - if !reflect.DeepEqual(fa.Index, fb.Index) || fa.Name != fb.Name || fa.Anonymous != fb.Anonymous || fa.Offset != fb.Offset || !reflect.DeepEqual(fa.Type, fb.Type) { - return false - } - } - return true -} diff --git a/vendor/github.com/cheekybits/genny/LICENSE b/vendor/github.com/mattn/go-pointer/LICENSE similarity index 96% rename from vendor/github.com/cheekybits/genny/LICENSE rename to vendor/github.com/mattn/go-pointer/LICENSE index 519d7f227..5794eddcd 100644 --- a/vendor/github.com/cheekybits/genny/LICENSE +++ b/vendor/github.com/mattn/go-pointer/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 cheekybits +Copyright (c) 2019 Yasuhiro Matsumoto Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/vendor/github.com/mattn/go-pointer/README.md b/vendor/github.com/mattn/go-pointer/README.md new file mode 100644 index 000000000..c74eee22a --- /dev/null +++ b/vendor/github.com/mattn/go-pointer/README.md @@ -0,0 +1,29 @@ +# go-pointer + +Utility for cgo + +## Usage + +https://github.com/golang/proposal/blob/master/design/12416-cgo-pointers.md + +In go 1.6, cgo argument can't be passed Go pointer. + +``` +var s string +C.pass_pointer(pointer.Save(&s)) +v := *(pointer.Restore(C.get_from_pointer()).(*string)) +``` + +## Installation + +``` +go get github.com/mattn/go-pointer +``` + +## License + +MIT + +## Author + +Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-pointer/_example/callback.h b/vendor/github.com/mattn/go-pointer/_example/callback.h new file mode 100644 index 000000000..4dbed45b3 --- /dev/null +++ b/vendor/github.com/mattn/go-pointer/_example/callback.h @@ -0,0 +1,9 @@ +#include + +typedef void (*callback)(void*); + +static void call_later(int delay, callback cb, void* data) { + sleep(delay); + cb(data); +} + diff --git a/vendor/github.com/mattn/go-pointer/doc.go b/vendor/github.com/mattn/go-pointer/doc.go new file mode 100644 index 000000000..c27bd8c05 --- /dev/null +++ b/vendor/github.com/mattn/go-pointer/doc.go @@ -0,0 +1 @@ +package pointer diff --git a/vendor/github.com/mattn/go-pointer/pointer.go b/vendor/github.com/mattn/go-pointer/pointer.go new file mode 100644 index 000000000..08a985339 --- /dev/null +++ b/vendor/github.com/mattn/go-pointer/pointer.go @@ -0,0 +1,57 @@ +package pointer + +// #include +import "C" +import ( + "sync" + "unsafe" +) + +var ( + mutex sync.RWMutex + store = map[unsafe.Pointer]interface{}{} +) + +func Save(v interface{}) unsafe.Pointer { + if v == nil { + return nil + } + + // Generate real fake C pointer. + // This pointer will not store any data, but will bi used for indexing purposes. + // Since Go doest allow to cast dangling pointer to unsafe.Pointer, we do rally allocate one byte. + // Why we need indexing, because Go doest allow C code to store pointers to Go data. + var ptr unsafe.Pointer = C.malloc(C.size_t(1)) + if ptr == nil { + panic("can't allocate 'cgo-pointer hack index pointer': ptr == nil") + } + + mutex.Lock() + store[ptr] = v + mutex.Unlock() + + return ptr +} + +func Restore(ptr unsafe.Pointer) (v interface{}) { + if ptr == nil { + return nil + } + + mutex.RLock() + v = store[ptr] + mutex.RUnlock() + return +} + +func Unref(ptr unsafe.Pointer) { + if ptr == nil { + return + } + + mutex.Lock() + delete(store, ptr) + mutex.Unlock() + + C.free(ptr) +} diff --git a/vendor/github.com/multiformats/go-base32/base32.go b/vendor/github.com/multiformats/go-base32/base32.go index 8c43b6f5d..de7fd7901 100644 --- a/vendor/github.com/multiformats/go-base32/base32.go +++ b/vendor/github.com/multiformats/go-base32/base32.go @@ -93,7 +93,7 @@ func (enc Encoding) WithPadding(padding rune) *Encoding { // RFC 4648. var StdEncoding = NewEncodingCI(encodeStd) -// HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648. +// HexEncoding is the “Extended Hex Alphabet” defined in RFC 4648. // It is typically used in DNS. var HexEncoding = NewEncodingCI(encodeHex) @@ -226,6 +226,7 @@ func (e *encoder) Write(p []byte) (n int, err error) { } // Trailing fringe. + //lint:ignore S1001 fixed-length 5-byte slice for i := 0; i < len(p); i++ { e.buf[i] = p[i] } diff --git a/vendor/github.com/multiformats/go-base32/version.json b/vendor/github.com/multiformats/go-base32/version.json new file mode 100644 index 000000000..557859c53 --- /dev/null +++ b/vendor/github.com/multiformats/go-base32/version.json @@ -0,0 +1,3 @@ +{ + "version": "v0.1.0" +} diff --git a/vendor/github.com/multiformats/go-multiaddr/doc.go b/vendor/github.com/multiformats/go-multiaddr/doc.go index d8c37b265..b80f3ab2c 100644 --- a/vendor/github.com/multiformats/go-multiaddr/doc.go +++ b/vendor/github.com/multiformats/go-multiaddr/doc.go @@ -7,30 +7,29 @@ Learn more at https://github.com/multiformats/multiaddr Basic Use: - import ( - "bytes" - "strings" - ma "github.com/multiformats/go-multiaddr" - ) + import ( + "bytes" + "strings" + ma "github.com/multiformats/go-multiaddr" + ) - // construct from a string (err signals parse failure) - m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") + // construct from a string (err signals parse failure) + m1, err := ma.NewMultiaddr("/ip4/127.0.0.1/udp/1234") - // construct from bytes (err signals parse failure) - m2, err := ma.NewMultiaddrBytes(m1.Bytes()) + // construct from bytes (err signals parse failure) + m2, err := ma.NewMultiaddrBytes(m1.Bytes()) - // true - strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") - strings.Equal(m1.String(), m2.String()) - bytes.Equal(m1.Bytes(), m2.Bytes()) - m1.Equal(m2) - m2.Equal(m1) - - // tunneling (en/decap) - printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") - proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") - printerOverProxy := proxy.Encapsulate(printer) - proxyAgain := printerOverProxy.Decapsulate(printer) + // true + strings.Equal(m1.String(), "/ip4/127.0.0.1/udp/1234") + strings.Equal(m1.String(), m2.String()) + bytes.Equal(m1.Bytes(), m2.Bytes()) + m1.Equal(m2) + m2.Equal(m1) + // tunneling (en/decap) + printer, _ := ma.NewMultiaddr("/ip4/192.168.0.13/tcp/80") + proxy, _ := ma.NewMultiaddr("/ip4/10.20.30.40/tcp/443") + printerOverProxy := proxy.Encapsulate(printer) + proxyAgain := printerOverProxy.Decapsulate(printer) */ package multiaddr diff --git a/vendor/github.com/multiformats/go-multiaddr/filter.go b/vendor/github.com/multiformats/go-multiaddr/filter.go index cc13aeeb6..ba915da00 100644 --- a/vendor/github.com/multiformats/go-multiaddr/filter.go +++ b/vendor/github.com/multiformats/go-multiaddr/filter.go @@ -85,8 +85,9 @@ func (fs *Filters) RemoveLiteral(ipnet net.IPNet) (removed bool) { // default is returned. // // TODO: currently, the last filter to match wins always, but it shouldn't be that way. -// Instead, the highest-specific last filter should win; that way more specific filters -// override more general ones. +// +// Instead, the highest-specific last filter should win; that way more specific filters +// override more general ones. func (fs *Filters) AddrBlocked(a Multiaddr) (deny bool) { var ( netip net.IP diff --git a/vendor/github.com/multiformats/go-multiaddr/interface.go b/vendor/github.com/multiformats/go-multiaddr/interface.go index 82cc76401..699c54d1d 100644 --- a/vendor/github.com/multiformats/go-multiaddr/interface.go +++ b/vendor/github.com/multiformats/go-multiaddr/interface.go @@ -12,11 +12,10 @@ Learn more here: https://github.com/multiformats/multiaddr Multiaddrs have both a binary and string representation. - import ma "github.com/multiformats/go-multiaddr" - - addr, err := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/80") - // err non-nil when parsing failed. + import ma "github.com/multiformats/go-multiaddr" + addr, err := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/80") + // err non-nil when parsing failed. */ type Multiaddr interface { json.Marshaler @@ -48,9 +47,11 @@ type Multiaddr interface { // Encapsulate(Multiaddr) Multiaddr - // Decapsultate removes a Multiaddr wrapping. For example: + // Decapsulate removes a Multiaddr wrapping. For example: // - // /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = /tcp/80 + // /ip4/1.2.3.4/tcp/80 decapsulate /tcp/80 = /ip4/1.2.3.4 + // /ip4/1.2.3.4/tcp/80 decapsulate /udp/80 = /ip4/1.2.3.4/tcp/80 + // /ip4/1.2.3.4/tcp/80 decapsulate /ip4/1.2.3.4 = nil // Decapsulate(Multiaddr) Multiaddr diff --git a/vendor/github.com/multiformats/go-multiaddr/net/net.go b/vendor/github.com/multiformats/go-multiaddr/net/net.go index 16f1bbc53..10fcff700 100644 --- a/vendor/github.com/multiformats/go-multiaddr/net/net.go +++ b/vendor/github.com/multiformats/go-multiaddr/net/net.go @@ -81,11 +81,11 @@ func wrap(nconn net.Conn, laddr, raddr ma.Multiaddr) Conn { // This function does it's best to avoid "hiding" methods exposed by the wrapped // type. Guarantees: // -// * If the wrapped connection exposes the "half-open" closer methods -// (CloseWrite, CloseRead), these will be available on the wrapped connection -// via type assertions. -// * If the wrapped connection is a UnixConn, IPConn, TCPConn, or UDPConn, all -// methods on these wrapped connections will be available via type assertions. +// - If the wrapped connection exposes the "half-open" closer methods +// (CloseWrite, CloseRead), these will be available on the wrapped connection +// via type assertions. +// - If the wrapped connection is a UnixConn, IPConn, TCPConn, or UDPConn, all +// methods on these wrapped connections will be available via type assertions. func WrapNetConn(nconn net.Conn) (Conn, error) { if nconn == nil { return nil, fmt.Errorf("failed to convert nconn.LocalAddr: nil") @@ -224,9 +224,9 @@ func (nla *netListenerAdapter) Accept() (net.Conn, error) { // NetListener turns this Listener into a net.Listener. // -// * Connections returned from Accept implement multiaddr/net Conn. -// * Calling WrapNetListener on the net.Listener returned by this function will -// return the original (underlying) multiaddr/net Listener. +// - Connections returned from Accept implement multiaddr/net Conn. +// - Calling WrapNetListener on the net.Listener returned by this function will +// return the original (underlying) multiaddr/net Listener. func NetListener(l Listener) net.Listener { return &netListenerAdapter{l} } diff --git a/vendor/github.com/multiformats/go-multiaddr/protocols.go b/vendor/github.com/multiformats/go-multiaddr/protocols.go index 28b395995..d226efa62 100644 --- a/vendor/github.com/multiformats/go-multiaddr/protocols.go +++ b/vendor/github.com/multiformats/go-multiaddr/protocols.go @@ -3,39 +3,41 @@ package multiaddr // You **MUST** register your multicodecs with // https://github.com/multiformats/multicodec before adding them here. const ( - P_IP4 = 0x0004 - P_TCP = 0x0006 - P_DNS = 0x0035 // 4 or 6 - P_DNS4 = 0x0036 - P_DNS6 = 0x0037 - P_DNSADDR = 0x0038 - P_UDP = 0x0111 - P_DCCP = 0x0021 - P_IP6 = 0x0029 - P_IP6ZONE = 0x002A - P_IPCIDR = 0x002B - P_QUIC = 0x01CC - P_WEBTRANSPORT = 0x01D1 - P_CERTHASH = 0x01D2 - P_SCTP = 0x0084 - P_CIRCUIT = 0x0122 - P_UDT = 0x012D - P_UTP = 0x012E - P_UNIX = 0x0190 - P_P2P = 0x01A5 - P_IPFS = 0x01A5 // alias for backwards compatibility - P_HTTP = 0x01E0 - P_HTTPS = 0x01BB // deprecated alias for /tls/http - P_ONION = 0x01BC // also for backwards compatibility - P_ONION3 = 0x01BD - P_GARLIC64 = 0x01BE - P_GARLIC32 = 0x01BF - P_P2P_WEBRTC_DIRECT = 0x0114 - P_TLS = 0x01c0 - P_NOISE = 0x01c6 - P_WS = 0x01DD - P_WSS = 0x01DE // deprecated alias for /tls/ws - P_PLAINTEXTV2 = 0x706c61 + P_IP4 = 4 + P_TCP = 6 + P_DNS = 53 // 4 or 6 + P_DNS4 = 54 + P_DNS6 = 55 + P_DNSADDR = 56 + P_UDP = 273 + P_DCCP = 33 + P_IP6 = 41 + P_IP6ZONE = 42 + P_IPCIDR = 43 + P_QUIC = 460 + P_WEBTRANSPORT = 465 + P_CERTHASH = 466 + P_SCTP = 132 + P_CIRCUIT = 290 + P_UDT = 301 + P_UTP = 302 + P_UNIX = 400 + P_P2P = 421 + P_IPFS = P_P2P // alias for backwards compatibility + P_HTTP = 480 + P_HTTPS = 443 // deprecated alias for /tls/http + P_ONION = 444 // also for backwards compatibility + P_ONION3 = 445 + P_GARLIC64 = 446 + P_GARLIC32 = 447 + P_P2P_WEBRTC_DIRECT = 276 + P_TLS = 448 + P_SNI = 449 + P_NOISE = 454 + P_WS = 477 + P_WSS = 478 // deprecated alias for /tls/ws + P_PLAINTEXTV2 = 7367777 + P_WEBRTC = 280 ) var ( @@ -227,6 +229,13 @@ var ( Code: P_TLS, VCode: CodeToVarint(P_TLS), } + protoSNI = Protocol{ + Name: "sni", + Size: LengthPrefixedVarSize, + Code: P_SNI, + VCode: CodeToVarint(P_SNI), + Transcoder: TranscoderDns, + } protoNOISE = Protocol{ Name: "noise", Code: P_NOISE, @@ -247,6 +256,11 @@ var ( Code: P_WSS, VCode: CodeToVarint(P_WSS), } + protoWebRTC = Protocol{ + Name: "webrtc", + Code: P_WEBRTC, + VCode: CodeToVarint(P_WEBRTC), + } ) func init() { @@ -279,10 +293,12 @@ func init() { protoUNIX, protoP2P_WEBRTC_DIRECT, protoTLS, + protoSNI, protoNOISE, protoWS, protoWSS, protoPlaintextV2, + protoWebRTC, } { if err := AddProtocol(p); err != nil { panic(err) diff --git a/vendor/github.com/multiformats/go-multiaddr/version.json b/vendor/github.com/multiformats/go-multiaddr/version.json index 42c14d1be..9f6d6fca3 100644 --- a/vendor/github.com/multiformats/go-multiaddr/version.json +++ b/vendor/github.com/multiformats/go-multiaddr/version.json @@ -1,3 +1,3 @@ { - "version": "v0.6.0" + "version": "v0.7.0" } diff --git a/vendor/github.com/multiformats/go-multicodec/version.json b/vendor/github.com/multiformats/go-multicodec/version.json index fc15ae013..42c14d1be 100644 --- a/vendor/github.com/multiformats/go-multicodec/version.json +++ b/vendor/github.com/multiformats/go-multicodec/version.json @@ -1,3 +1,3 @@ { - "version": "v0.5.0" + "version": "v0.6.0" } diff --git a/vendor/github.com/multiformats/go-multihash/core/magic.go b/vendor/github.com/multiformats/go-multihash/core/magic.go index d604026a0..b85e9a610 100644 --- a/vendor/github.com/multiformats/go-multihash/core/magic.go +++ b/vendor/github.com/multiformats/go-multihash/core/magic.go @@ -5,6 +5,9 @@ import "errors" // ErrSumNotSupported is returned when the Sum function code is not implemented var ErrSumNotSupported = errors.New("no such hash registered") +// ErrLenTooLarge is returned when the hash function cannot produce the requested number of bytes +var ErrLenTooLarge = errors.New("requested length was too large for digest") + // constants const ( IDENTITY = 0x00 diff --git a/vendor/github.com/multiformats/go-multihash/core/registry.go b/vendor/github.com/multiformats/go-multihash/core/registry.go index af27836bb..4077f2bac 100644 --- a/vendor/github.com/multiformats/go-multihash/core/registry.go +++ b/vendor/github.com/multiformats/go-multihash/core/registry.go @@ -10,7 +10,8 @@ import ( ) // registry is a simple map which maps a multihash indicator number -// to a standard golang Hash interface. +// to a function : (size:int) -> ((hasher:hash.Hash), (bool:success)) +// The function may error (i.e., return (nil, false)) to signify that the hasher can't return that many bytes. // // Multihash indicator numbers are reserved and described in // https://github.com/multiformats/multicodec/blob/master/table.csv . @@ -18,7 +19,7 @@ import ( // // Hashers which are available in the golang stdlib will be registered automatically. // Others can be added using the Register function. -var registry = make(map[uint64]func() hash.Hash) +var registry = make(map[uint64]func(int) (h hash.Hash, ok bool)) // Register adds a new hash to the set available from GetHasher and Sum. // @@ -37,8 +38,34 @@ func Register(indicator uint64, hasherFactory func() hash.Hash) { if hasherFactory == nil { panic("not sensible to attempt to register a nil function") } + maxSize := hasherFactory().Size() + registry[indicator] = func(size int) (hash.Hash, bool) { + if size > maxSize { + return nil, false + } + return hasherFactory(), true + } + DefaultLengths[indicator] = maxSize +} + +// RegisterVariableSize is like Register, but adds a new variable-sized hasher factory that takes a +// size hint. +// +// When passed -1, the hasher should produce digests with the hash-function's default length. When +// passed a non-negative integer, the hasher should try to produce digests of at least the specified +// size. +func RegisterVariableSize(indicator uint64, hasherFactory func(sizeHint int) (hash.Hash, bool)) { + if hasherFactory == nil { + panic("not sensible to attempt to register a nil function") + } + + if hasher, ok := hasherFactory(-1); !ok { + panic("failed to determine default hash length for hasher") + } else { + DefaultLengths[indicator] = hasher.Size() + } + registry[indicator] = hasherFactory - DefaultLengths[indicator] = hasherFactory().Size() } // GetHasher returns a new hash.Hash according to the indicator code number provided. @@ -54,11 +81,26 @@ func Register(indicator uint64, hasherFactory func() hash.Hash) { // // If an error is returned, it will match `errors.Is(err, ErrSumNotSupported)`. func GetHasher(indicator uint64) (hash.Hash, error) { + return GetVariableHasher(indicator, -1) +} + +// GetVariableHasher returns a new hash.Hash according to the indicator code number provided, with +// the specified size hint. +// +// NOTE: The size hint is only a hint. Hashers will attempt to produce at least the number of requested bytes, but may not. +// +// This function can fail if either the hash code is not registered, or the passed size hint is +// statically incompatible with the specified hash function. +func GetVariableHasher(indicator uint64, sizeHint int) (hash.Hash, error) { factory, exists := registry[indicator] if !exists { return nil, fmt.Errorf("unknown multihash code %d (0x%x): %w", indicator, indicator, ErrSumNotSupported) } - return factory(), nil + hasher, ok := factory(sizeHint) + if !ok { + return nil, ErrLenTooLarge + } + return hasher, nil } // DefaultLengths maps a multihash indicator code to the output size for that hash, in units of bytes. @@ -68,7 +110,7 @@ func GetHasher(indicator uint64) (hash.Hash, error) { var DefaultLengths = map[uint64]int{} func init() { - Register(IDENTITY, func() hash.Hash { return &identityMultihash{} }) + RegisterVariableSize(IDENTITY, func(_ int) (hash.Hash, bool) { return &identityMultihash{}, true }) Register(MD5, md5.New) Register(SHA1, sha1.New) Register(SHA2_224, sha256.New224) diff --git a/vendor/github.com/multiformats/go-multihash/multihash.go b/vendor/github.com/multiformats/go-multihash/multihash.go index 42ab977f8..58e631df5 100644 --- a/vendor/github.com/multiformats/go-multihash/multihash.go +++ b/vendor/github.com/multiformats/go-multihash/multihash.go @@ -27,11 +27,12 @@ var ( // ErrInconsistentLen is returned when a decoded multihash has an inconsistent length type ErrInconsistentLen struct { - dm *DecodedMultihash + dm *DecodedMultihash + lengthFound int } func (e ErrInconsistentLen) Error() string { - return fmt.Sprintf("multihash length inconsistent: expected %d, got %d", e.dm.Length, len(e.dm.Digest)) + return fmt.Sprintf("multihash length inconsistent: expected %d; got %d", e.dm.Length, e.lengthFound) } // constants @@ -143,6 +144,7 @@ var Codes = map[uint64]string{ MD5: "md5", } +// reads a varint from buf and returns bytes read. func uvarint(buf []byte) (uint64, []byte, error) { n, c, err := varint.FromUvarint(buf) if err != nil { @@ -233,7 +235,7 @@ func Decode(buf []byte) (*DecodedMultihash, error) { } if len(buf) != rlen { - return nil, ErrInconsistentLen{dm} + return nil, ErrInconsistentLen{dm, rlen} } return dm, nil @@ -264,8 +266,8 @@ func EncodeName(buf []byte, name string) ([]byte, error) { // Note: the returned digest is a slice over the passed in data and should be // copied if the buffer will be reused func readMultihashFromBuf(buf []byte) (int, uint64, []byte, error) { - bufl := len(buf) - if bufl < 2 { + initBufLength := len(buf) + if initBufLength < 2 { return 0, 0, nil, ErrTooShort } @@ -289,7 +291,8 @@ func readMultihashFromBuf(buf []byte) (int, uint64, []byte, error) { return 0, 0, nil, errors.New("length greater than remaining number of bytes in buffer") } - rlen := (bufl - len(buf)) + int(length) + // rlen is the advertised size of the CID + rlen := (initBufLength - len(buf)) + int(length) return rlen, code, buf[:length], nil } diff --git a/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go b/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go index c67058b9a..143fb57d6 100644 --- a/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go +++ b/vendor/github.com/multiformats/go-multihash/register/blake3/multihash_blake3.go @@ -17,7 +17,17 @@ import ( "github.com/multiformats/go-multihash/core" ) -func init() { - multihash.Register(multihash.BLAKE3, func() hash.Hash { h := blake3.New(32, nil); return h }) +const DefaultSize = 32 +const MaxSize = 128 +func init() { + multihash.RegisterVariableSize(multihash.BLAKE3, func(size int) (hash.Hash, bool) { + if size == -1 { + size = DefaultSize + } else if size > MaxSize || size <= 0 { + return nil, false + } + h := blake3.New(size, nil) + return h, true + }) } diff --git a/vendor/github.com/multiformats/go-multihash/sum.go b/vendor/github.com/multiformats/go-multihash/sum.go index d7d75c553..d40b5aabd 100644 --- a/vendor/github.com/multiformats/go-multihash/sum.go +++ b/vendor/github.com/multiformats/go-multihash/sum.go @@ -1,7 +1,6 @@ package multihash import ( - "errors" "fmt" "hash" "io" @@ -12,14 +11,14 @@ import ( // ErrSumNotSupported is returned when the Sum function code is not implemented var ErrSumNotSupported = mhreg.ErrSumNotSupported -var ErrLenTooLarge = errors.New("requested length was too large for digest") +var ErrLenTooLarge = mhreg.ErrLenTooLarge // Sum obtains the cryptographic sum of a given buffer. The length parameter // indicates the length of the resulting digest. Passing a negative value uses // default length values for the selected hash function. func Sum(data []byte, code uint64, length int) (Multihash, error) { // Get the algorithm. - hasher, err := GetHasher(code) + hasher, err := mhreg.GetVariableHasher(code, length) if err != nil { return nil, err } @@ -35,7 +34,7 @@ func Sum(data []byte, code uint64, length int) (Multihash, error) { // value uses default length values for the selected hash function. func SumStream(r io.Reader, code uint64, length int) (Multihash, error) { // Get the algorithm. - hasher, err := GetHasher(code) + hasher, err := mhreg.GetVariableHasher(code, length) if err != nil { return nil, err } diff --git a/vendor/github.com/multiformats/go-multihash/version.json b/vendor/github.com/multiformats/go-multihash/version.json index b9cc604bc..88bcb867b 100644 --- a/vendor/github.com/multiformats/go-multihash/version.json +++ b/vendor/github.com/multiformats/go-multihash/version.json @@ -1,3 +1,3 @@ { - "version": "v0.2.0" + "version": "v0.2.1" } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/collector.go b/vendor/github.com/prometheus/client_golang/prometheus/collector.go index ac1ca3cf5..cf05079fb 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/collector.go @@ -69,9 +69,9 @@ type Collector interface { // If a Collector collects the same metrics throughout its lifetime, its // Describe method can simply be implemented as: // -// func (c customCollector) Describe(ch chan<- *Desc) { -// DescribeByCollect(c, ch) -// } +// func (c customCollector) Describe(ch chan<- *Desc) { +// DescribeByCollect(c, ch) +// } // // However, this will not work if the metrics collected change dynamically over // the lifetime of the Collector in a way that their combined set of descriptors diff --git a/vendor/github.com/prometheus/client_golang/prometheus/counter.go b/vendor/github.com/prometheus/client_golang/prometheus/counter.go index 00d70f09b..de30de6da 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/counter.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/counter.go @@ -51,7 +51,7 @@ type Counter interface { // will lead to a valid (label-less) exemplar. But if Labels is nil, the current // exemplar is left in place. AddWithExemplar panics if the value is < 0, if any // of the provided labels are invalid, or if the provided labels contain more -// than 64 runes in total. +// than 128 runes in total. type ExemplarAdder interface { AddWithExemplar(value float64, exemplar Labels) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/desc.go b/vendor/github.com/prometheus/client_golang/prometheus/desc.go index 4bb816ab7..8bc5e44e2 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/desc.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/desc.go @@ -20,6 +20,9 @@ import ( "strings" "github.com/cespare/xxhash/v2" + + "github.com/prometheus/client_golang/prometheus/internal" + //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" "github.com/prometheus/common/model" @@ -154,7 +157,7 @@ func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) * Value: proto.String(v), }) } - sort.Sort(labelPairSorter(d.constLabelPairs)) + sort.Sort(internal.LabelPairSorter(d.constLabelPairs)) return d } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go new file mode 100644 index 000000000..614fd61be --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/get_pid.go @@ -0,0 +1,26 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !js || wasm +// +build !js wasm + +package prometheus + +import "os" + +func getPIDFn() func() (int, error) { + pid := os.Getpid() + return func() (int, error) { + return pid, nil + } +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go new file mode 100644 index 000000000..eaf8059ee --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/get_pid_gopherjs.go @@ -0,0 +1,23 @@ +// Copyright 2015 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build js && !wasm +// +build js,!wasm + +package prometheus + +func getPIDFn() func() (int, error) { + return func() (int, error) { + return 1, nil + } +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go index 08195b410..ad9a71a5e 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector.go @@ -19,6 +19,10 @@ import ( "time" ) +// goRuntimeMemStats provides the metrics initially provided by runtime.ReadMemStats. +// From Go 1.17 those similar (and better) statistics are provided by runtime/metrics, so +// while eval closure works on runtime.MemStats, the struct from Go 1.17+ is +// populated using runtime/metrics. func goRuntimeMemStats() memStatsMetrics { return memStatsMetrics{ { @@ -197,14 +201,6 @@ func goRuntimeMemStats() memStatsMetrics { ), eval: func(ms *runtime.MemStats) float64 { return float64(ms.NextGC) }, valType: GaugeValue, - }, { - desc: NewDesc( - memstatNamespace("gc_cpu_fraction"), - "The fraction of this program's available CPU time used by the GC since the program started.", - nil, nil, - ), - eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction }, - valType: GaugeValue, }, } } @@ -232,7 +228,7 @@ func newBaseGoCollector() baseGoCollector { "A summary of the pause duration of garbage collection cycles.", nil, nil), gcLastTimeDesc: NewDesc( - memstatNamespace("last_gc_time_seconds"), + "go_memstats_last_gc_time_seconds", "Number of seconds since 1970 of last garbage collection.", nil, nil), goInfoDesc: NewDesc( @@ -254,8 +250,9 @@ func (c *baseGoCollector) Describe(ch chan<- *Desc) { // Collect returns the current state of all metrics of the collector. func (c *baseGoCollector) Collect(ch chan<- Metric) { ch <- MustNewConstMetric(c.goroutinesDesc, GaugeValue, float64(runtime.NumGoroutine())) - n, _ := runtime.ThreadCreateProfile(nil) - ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, float64(n)) + + n := getRuntimeNumThreads() + ch <- MustNewConstMetric(c.threadsDesc, GaugeValue, n) var stats debug.GCStats stats.PauseQuantiles = make([]time.Duration, 5) @@ -268,7 +265,6 @@ func (c *baseGoCollector) Collect(ch chan<- Metric) { quantiles[0.0] = stats.PauseQuantiles[0].Seconds() ch <- MustNewConstSummary(c.gcDesc, uint64(stats.NumGC), stats.PauseTotal.Seconds(), quantiles) ch <- MustNewConstMetric(c.gcLastTimeDesc, GaugeValue, float64(stats.LastGC.UnixNano())/1e9) - ch <- MustNewConstMetric(c.goInfoDesc, GaugeValue, 1) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go index 24526131e..897a6e906 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go116.go @@ -40,13 +40,28 @@ type goCollector struct { // // Deprecated: Use collectors.NewGoCollector instead. func NewGoCollector() Collector { + msMetrics := goRuntimeMemStats() + msMetrics = append(msMetrics, struct { + desc *Desc + eval func(*runtime.MemStats) float64 + valType ValueType + }{ + // This metric is omitted in Go1.17+, see https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 + desc: NewDesc( + memstatNamespace("gc_cpu_fraction"), + "The fraction of this program's available CPU time used by the GC since the program started.", + nil, nil, + ), + eval: func(ms *runtime.MemStats) float64 { return ms.GCCPUFraction }, + valType: GaugeValue, + }) return &goCollector{ base: newBaseGoCollector(), msLast: &runtime.MemStats{}, msRead: runtime.ReadMemStats, msMaxWait: time.Second, msMaxAge: 5 * time.Minute, - msMetrics: goRuntimeMemStats(), + msMetrics: msMetrics, } } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go117.go b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go similarity index 53% rename from vendor/github.com/prometheus/client_golang/prometheus/go_collector_go117.go rename to vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go index d43bdcdda..3a2d55e84 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/go_collector_go117.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/go_collector_latest.go @@ -25,10 +25,72 @@ import ( //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. "github.com/golang/protobuf/proto" - "github.com/prometheus/client_golang/prometheus/internal" dto "github.com/prometheus/client_model/go" + + "github.com/prometheus/client_golang/prometheus/internal" ) +const ( + // constants for strings referenced more than once. + goGCHeapTinyAllocsObjects = "/gc/heap/tiny/allocs:objects" + goGCHeapAllocsObjects = "/gc/heap/allocs:objects" + goGCHeapFreesObjects = "/gc/heap/frees:objects" + goGCHeapFreesBytes = "/gc/heap/frees:bytes" + goGCHeapAllocsBytes = "/gc/heap/allocs:bytes" + goGCHeapObjects = "/gc/heap/objects:objects" + goGCHeapGoalBytes = "/gc/heap/goal:bytes" + goMemoryClassesTotalBytes = "/memory/classes/total:bytes" + goMemoryClassesHeapObjectsBytes = "/memory/classes/heap/objects:bytes" + goMemoryClassesHeapUnusedBytes = "/memory/classes/heap/unused:bytes" + goMemoryClassesHeapReleasedBytes = "/memory/classes/heap/released:bytes" + goMemoryClassesHeapFreeBytes = "/memory/classes/heap/free:bytes" + goMemoryClassesHeapStacksBytes = "/memory/classes/heap/stacks:bytes" + goMemoryClassesOSStacksBytes = "/memory/classes/os-stacks:bytes" + goMemoryClassesMetadataMSpanInuseBytes = "/memory/classes/metadata/mspan/inuse:bytes" + goMemoryClassesMetadataMSPanFreeBytes = "/memory/classes/metadata/mspan/free:bytes" + goMemoryClassesMetadataMCacheInuseBytes = "/memory/classes/metadata/mcache/inuse:bytes" + goMemoryClassesMetadataMCacheFreeBytes = "/memory/classes/metadata/mcache/free:bytes" + goMemoryClassesProfilingBucketsBytes = "/memory/classes/profiling/buckets:bytes" + goMemoryClassesMetadataOtherBytes = "/memory/classes/metadata/other:bytes" + goMemoryClassesOtherBytes = "/memory/classes/other:bytes" +) + +// rmNamesForMemStatsMetrics represents runtime/metrics names required to populate goRuntimeMemStats from like logic. +var rmNamesForMemStatsMetrics = []string{ + goGCHeapTinyAllocsObjects, + goGCHeapAllocsObjects, + goGCHeapFreesObjects, + goGCHeapAllocsBytes, + goGCHeapObjects, + goGCHeapGoalBytes, + goMemoryClassesTotalBytes, + goMemoryClassesHeapObjectsBytes, + goMemoryClassesHeapUnusedBytes, + goMemoryClassesHeapReleasedBytes, + goMemoryClassesHeapFreeBytes, + goMemoryClassesHeapStacksBytes, + goMemoryClassesOSStacksBytes, + goMemoryClassesMetadataMSpanInuseBytes, + goMemoryClassesMetadataMSPanFreeBytes, + goMemoryClassesMetadataMCacheInuseBytes, + goMemoryClassesMetadataMCacheFreeBytes, + goMemoryClassesProfilingBucketsBytes, + goMemoryClassesMetadataOtherBytes, + goMemoryClassesOtherBytes, +} + +func bestEffortLookupRM(lookup []string) []metrics.Description { + ret := make([]metrics.Description, 0, len(lookup)) + for _, rm := range metrics.All() { + for _, m := range lookup { + if m == rm.Name { + ret = append(ret, rm) + } + } + } + return ret +} + type goCollector struct { base baseGoCollector @@ -36,70 +98,124 @@ type goCollector struct { // snapshot is always produced by Collect. mu sync.Mutex - // rm... fields all pertain to the runtime/metrics package. - rmSampleBuf []metrics.Sample - rmSampleMap map[string]*metrics.Sample - rmMetrics []collectorMetric + // Contains all samples that has to retrieved from runtime/metrics (not all of them will be exposed). + sampleBuf []metrics.Sample + // sampleMap allows lookup for MemStats metrics and runtime/metrics histograms for exact sums. + sampleMap map[string]*metrics.Sample + + // rmExposedMetrics represents all runtime/metrics package metrics + // that were configured to be exposed. + rmExposedMetrics []collectorMetric + rmExactSumMapForHist map[string]string // With Go 1.17, the runtime/metrics package was introduced. // From that point on, metric names produced by the runtime/metrics // package could be generated from runtime/metrics names. However, // these differ from the old names for the same values. // - // This field exist to export the same values under the old names + // This field exists to export the same values under the old names // as well. - msMetrics memStatsMetrics + msMetrics memStatsMetrics + msMetricsEnabled bool +} + +type rmMetricDesc struct { + metrics.Description +} + +func matchRuntimeMetricsRules(rules []internal.GoCollectorRule) []rmMetricDesc { + var descs []rmMetricDesc + for _, d := range metrics.All() { + var ( + deny = true + desc rmMetricDesc + ) + + for _, r := range rules { + if !r.Matcher.MatchString(d.Name) { + continue + } + deny = r.Deny + } + if deny { + continue + } + + desc.Description = d + descs = append(descs, desc) + } + return descs +} + +func defaultGoCollectorOptions() internal.GoCollectorOptions { + return internal.GoCollectorOptions{ + RuntimeMetricSumForHist: map[string]string{ + "/gc/heap/allocs-by-size:bytes": goGCHeapAllocsBytes, + "/gc/heap/frees-by-size:bytes": goGCHeapFreesBytes, + }, + RuntimeMetricRules: []internal.GoCollectorRule{ + //{Matcher: regexp.MustCompile("")}, + }, + } } // NewGoCollector is the obsolete version of collectors.NewGoCollector. // See there for documentation. // // Deprecated: Use collectors.NewGoCollector instead. -func NewGoCollector() Collector { - descriptions := metrics.All() +func NewGoCollector(opts ...func(o *internal.GoCollectorOptions)) Collector { + opt := defaultGoCollectorOptions() + for _, o := range opts { + o(&opt) + } + + exposedDescriptions := matchRuntimeMetricsRules(opt.RuntimeMetricRules) // Collect all histogram samples so that we can get their buckets. // The API guarantees that the buckets are always fixed for the lifetime // of the process. var histograms []metrics.Sample - for _, d := range descriptions { + for _, d := range exposedDescriptions { if d.Kind == metrics.KindFloat64Histogram { histograms = append(histograms, metrics.Sample{Name: d.Name}) } } - metrics.Read(histograms) + + if len(histograms) > 0 { + metrics.Read(histograms) + } + bucketsMap := make(map[string][]float64) for i := range histograms { bucketsMap[histograms[i].Name] = histograms[i].Value.Float64Histogram().Buckets } - // Generate a Desc and ValueType for each runtime/metrics metric. - metricSet := make([]collectorMetric, 0, len(descriptions)) - sampleBuf := make([]metrics.Sample, 0, len(descriptions)) - sampleMap := make(map[string]*metrics.Sample, len(descriptions)) - for i := range descriptions { - d := &descriptions[i] - namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(d) + // Generate a collector for each exposed runtime/metrics metric. + metricSet := make([]collectorMetric, 0, len(exposedDescriptions)) + // SampleBuf is used for reading from runtime/metrics. + // We are assuming the largest case to have stable pointers for sampleMap purposes. + sampleBuf := make([]metrics.Sample, 0, len(exposedDescriptions)+len(opt.RuntimeMetricSumForHist)+len(rmNamesForMemStatsMetrics)) + sampleMap := make(map[string]*metrics.Sample, len(exposedDescriptions)) + for _, d := range exposedDescriptions { + namespace, subsystem, name, ok := internal.RuntimeMetricsToProm(&d.Description) if !ok { // Just ignore this metric; we can't do anything with it here. // If a user decides to use the latest version of Go, we don't want - // to fail here. This condition is tested elsewhere. + // to fail here. This condition is tested in TestExpectedRuntimeMetrics. continue } - // Set up sample buffer for reading, and a map - // for quick lookup of sample values. sampleBuf = append(sampleBuf, metrics.Sample{Name: d.Name}) sampleMap[d.Name] = &sampleBuf[len(sampleBuf)-1] var m collectorMetric if d.Kind == metrics.KindFloat64Histogram { - _, hasSum := rmExactSumMap[d.Name] + _, hasSum := opt.RuntimeMetricSumForHist[d.Name] unit := d.Name[strings.IndexRune(d.Name, ':')+1:] m = newBatchHistogram( NewDesc( BuildFQName(namespace, subsystem, name), - d.Description, + d.Description.Description, nil, nil, ), @@ -111,24 +227,61 @@ func NewGoCollector() Collector { Namespace: namespace, Subsystem: subsystem, Name: name, - Help: d.Description, - }) + Help: d.Description.Description, + }, + ) } else { m = NewGauge(GaugeOpts{ Namespace: namespace, Subsystem: subsystem, Name: name, - Help: d.Description, + Help: d.Description.Description, }) } metricSet = append(metricSet, m) } + + // Add exact sum metrics to sampleBuf if not added before. + for _, h := range histograms { + sumMetric, ok := opt.RuntimeMetricSumForHist[h.Name] + if !ok { + continue + } + + if _, ok := sampleMap[sumMetric]; ok { + continue + } + sampleBuf = append(sampleBuf, metrics.Sample{Name: sumMetric}) + sampleMap[sumMetric] = &sampleBuf[len(sampleBuf)-1] + } + + var ( + msMetrics memStatsMetrics + msDescriptions []metrics.Description + ) + + if !opt.DisableMemStatsLikeMetrics { + msMetrics = goRuntimeMemStats() + msDescriptions = bestEffortLookupRM(rmNamesForMemStatsMetrics) + + // Check if metric was not exposed before and if not, add to sampleBuf. + for _, mdDesc := range msDescriptions { + if _, ok := sampleMap[mdDesc.Name]; ok { + continue + } + sampleBuf = append(sampleBuf, metrics.Sample{Name: mdDesc.Name}) + sampleMap[mdDesc.Name] = &sampleBuf[len(sampleBuf)-1] + } + } + return &goCollector{ - base: newBaseGoCollector(), - rmSampleBuf: sampleBuf, - rmSampleMap: sampleMap, - rmMetrics: metricSet, - msMetrics: goRuntimeMemStats(), + base: newBaseGoCollector(), + sampleBuf: sampleBuf, + sampleMap: sampleMap, + rmExposedMetrics: metricSet, + rmExactSumMapForHist: opt.RuntimeMetricSumForHist, + msMetrics: msMetrics, + msMetricsEnabled: !opt.DisableMemStatsLikeMetrics, } } @@ -138,7 +291,7 @@ func (c *goCollector) Describe(ch chan<- *Desc) { for _, i := range c.msMetrics { ch <- i.desc } - for _, m := range c.rmMetrics { + for _, m := range c.rmExposedMetrics { ch <- m.Desc() } } @@ -148,8 +301,12 @@ func (c *goCollector) Collect(ch chan<- Metric) { // Collect base non-memory metrics. c.base.Collect(ch) + if len(c.sampleBuf) == 0 { + return + } + // Collect must be thread-safe, so prevent concurrent use of - // rmSampleBuf. Just read into rmSampleBuf but write all the data + // sampleBuf elements. Just read into sampleBuf but write all the data // we get into our Metrics or MemStats. // // This lock also ensures that the Metrics we send out are all from @@ -164,14 +321,17 @@ func (c *goCollector) Collect(ch chan<- Metric) { defer c.mu.Unlock() // Populate runtime/metrics sample buffer. - metrics.Read(c.rmSampleBuf) + metrics.Read(c.sampleBuf) + + // Collect all our runtime/metrics user chose to expose from sampleBuf (if any). + for i, metric := range c.rmExposedMetrics { + // We created samples for exposed metrics first in order, so indexes match. + sample := c.sampleBuf[i] - // Update all our metrics from rmSampleBuf. - for i, sample := range c.rmSampleBuf { // N.B. switch on concrete type because it's significantly more efficient // than checking for the Counter and Gauge interface implementations. In // this case, we control all the types here. - switch m := c.rmMetrics[i].(type) { + switch m := metric.(type) { case *counter: // Guard against decreases. This should never happen, but a failure // to do so will result in a panic, which is a harsh consequence for @@ -191,12 +351,15 @@ func (c *goCollector) Collect(ch chan<- Metric) { panic("unexpected metric type") } } - // ms is a dummy MemStats that we populate ourselves so that we can - // populate the old metrics from it. - var ms runtime.MemStats - memStatsFromRM(&ms, c.rmSampleMap) - for _, i := range c.msMetrics { - ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms)) + + if c.msMetricsEnabled { + // ms is a dummy MemStats that we populate ourselves so that we can + // populate the old metrics from it if goMemStatsCollection is enabled. + var ms runtime.MemStats + memStatsFromRM(&ms, c.sampleMap) + for _, i := range c.msMetrics { + ch <- MustNewConstMetric(i.desc, i.valType, i.eval(&ms)) + } } } @@ -224,11 +387,6 @@ func unwrapScalarRMValue(v metrics.Value) float64 { } } -var rmExactSumMap = map[string]string{ - "/gc/heap/allocs-by-size:bytes": "/gc/heap/allocs:bytes", - "/gc/heap/frees-by-size:bytes": "/gc/heap/frees:bytes", -} - // exactSumFor takes a runtime/metrics metric name (that is assumed to // be of kind KindFloat64Histogram) and returns its exact sum and whether // its exact sum exists. @@ -236,11 +394,11 @@ var rmExactSumMap = map[string]string{ // The runtime/metrics API for histograms doesn't currently expose exact // sums, but some of the other metrics are in fact exact sums of histograms. func (c *goCollector) exactSumFor(rmName string) float64 { - sumName, ok := rmExactSumMap[rmName] + sumName, ok := c.rmExactSumMapForHist[rmName] if !ok { return 0 } - s, ok := c.rmSampleMap[sumName] + s, ok := c.sampleMap[sumName] if !ok { return 0 } @@ -261,35 +419,30 @@ func memStatsFromRM(ms *runtime.MemStats, rm map[string]*metrics.Sample) { // while having Mallocs - Frees still represent a live object count. // Unfortunately, MemStats doesn't actually export a large allocation count, // so it's impossible to pull this number out directly. - tinyAllocs := lookupOrZero("/gc/heap/tiny/allocs:objects") - ms.Mallocs = lookupOrZero("/gc/heap/allocs:objects") + tinyAllocs - ms.Frees = lookupOrZero("/gc/heap/frees:objects") + tinyAllocs + tinyAllocs := lookupOrZero(goGCHeapTinyAllocsObjects) + ms.Mallocs = lookupOrZero(goGCHeapAllocsObjects) + tinyAllocs + ms.Frees = lookupOrZero(goGCHeapFreesObjects) + tinyAllocs - ms.TotalAlloc = lookupOrZero("/gc/heap/allocs:bytes") - ms.Sys = lookupOrZero("/memory/classes/total:bytes") + ms.TotalAlloc = lookupOrZero(goGCHeapAllocsBytes) + ms.Sys = lookupOrZero(goMemoryClassesTotalBytes) ms.Lookups = 0 // Already always zero. - ms.HeapAlloc = lookupOrZero("/memory/classes/heap/objects:bytes") + ms.HeapAlloc = lookupOrZero(goMemoryClassesHeapObjectsBytes) ms.Alloc = ms.HeapAlloc - ms.HeapInuse = ms.HeapAlloc + lookupOrZero("/memory/classes/heap/unused:bytes") - ms.HeapReleased = lookupOrZero("/memory/classes/heap/released:bytes") - ms.HeapIdle = ms.HeapReleased + lookupOrZero("/memory/classes/heap/free:bytes") + ms.HeapInuse = ms.HeapAlloc + lookupOrZero(goMemoryClassesHeapUnusedBytes) + ms.HeapReleased = lookupOrZero(goMemoryClassesHeapReleasedBytes) + ms.HeapIdle = ms.HeapReleased + lookupOrZero(goMemoryClassesHeapFreeBytes) ms.HeapSys = ms.HeapInuse + ms.HeapIdle - ms.HeapObjects = lookupOrZero("/gc/heap/objects:objects") - ms.StackInuse = lookupOrZero("/memory/classes/heap/stacks:bytes") - ms.StackSys = ms.StackInuse + lookupOrZero("/memory/classes/os-stacks:bytes") - ms.MSpanInuse = lookupOrZero("/memory/classes/metadata/mspan/inuse:bytes") - ms.MSpanSys = ms.MSpanInuse + lookupOrZero("/memory/classes/metadata/mspan/free:bytes") - ms.MCacheInuse = lookupOrZero("/memory/classes/metadata/mcache/inuse:bytes") - ms.MCacheSys = ms.MCacheInuse + lookupOrZero("/memory/classes/metadata/mcache/free:bytes") - ms.BuckHashSys = lookupOrZero("/memory/classes/profiling/buckets:bytes") - ms.GCSys = lookupOrZero("/memory/classes/metadata/other:bytes") - ms.OtherSys = lookupOrZero("/memory/classes/other:bytes") - ms.NextGC = lookupOrZero("/gc/heap/goal:bytes") - - // N.B. LastGC is omitted because runtime.GCStats already has this. - // See https://github.com/prometheus/client_golang/issues/842#issuecomment-861812034 - // for more details. - ms.LastGC = 0 + ms.HeapObjects = lookupOrZero(goGCHeapObjects) + ms.StackInuse = lookupOrZero(goMemoryClassesHeapStacksBytes) + ms.StackSys = ms.StackInuse + lookupOrZero(goMemoryClassesOSStacksBytes) + ms.MSpanInuse = lookupOrZero(goMemoryClassesMetadataMSpanInuseBytes) + ms.MSpanSys = ms.MSpanInuse + lookupOrZero(goMemoryClassesMetadataMSPanFreeBytes) + ms.MCacheInuse = lookupOrZero(goMemoryClassesMetadataMCacheInuseBytes) + ms.MCacheSys = ms.MCacheInuse + lookupOrZero(goMemoryClassesMetadataMCacheFreeBytes) + ms.BuckHashSys = lookupOrZero(goMemoryClassesProfilingBucketsBytes) + ms.GCSys = lookupOrZero(goMemoryClassesMetadataOtherBytes) + ms.OtherSys = lookupOrZero(goMemoryClassesOtherBytes) + ms.NextGC = lookupOrZero(goGCHeapGoalBytes) // N.B. GCCPUFraction is intentionally omitted. This metric is not useful, // and often misleading due to the fact that it's an average over the lifetime @@ -324,6 +477,11 @@ type batchHistogram struct { // buckets must always be from the runtime/metrics package, following // the same conventions. func newBatchHistogram(desc *Desc, buckets []float64, hasSum bool) *batchHistogram { + // We need to remove -Inf values. runtime/metrics keeps them around. + // But -Inf bucket should not be allowed for prometheus histograms. + if buckets[0] == math.Inf(-1) { + buckets = buckets[1:] + } h := &batchHistogram{ desc: desc, buckets: buckets, @@ -382,8 +540,10 @@ func (h *batchHistogram) Write(out *dto.Metric) error { for i, count := range h.counts { totalCount += count if !h.hasSum { - // N.B. This computed sum is an underestimate. - sum += h.buckets[i] * float64(count) + if count != 0 { + // N.B. This computed sum is an underestimate. + sum += h.buckets[i] * float64(count) + } } // Skip the +Inf bucket, but only for the bucket list. diff --git a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go index 893802fd6..0d47fecdc 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/histogram.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/histogram.go @@ -581,11 +581,11 @@ func (h *constHistogram) Desc() *Desc { func (h *constHistogram) Write(out *dto.Metric) error { his := &dto.Histogram{} + buckets := make([]*dto.Bucket, 0, len(h.buckets)) his.SampleCount = proto.Uint64(h.count) his.SampleSum = proto.Float64(h.sum) - for upperBound, count := range h.buckets { buckets = append(buckets, &dto.Bucket{ CumulativeCount: proto.Uint64(count), diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go new file mode 100644 index 000000000..fd45cadc0 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/difflib.go @@ -0,0 +1,651 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// It provides tools to compare sequences of strings and generate textual diffs. +// +// Maintaining `GetUnifiedDiffString` here because original repository +// (https://github.com/pmezard/go-difflib) is no loger maintained. +package internal + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strings" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func calculateRatio(matches, length int) float64 { + if length > 0 { + return 2.0 * float64(matches) / float64(length) + } + return 1.0 +} + +type Match struct { + A int + B int + Size int +} + +type OpCode struct { + Tag byte + I1 int + I2 int + J1 int + J2 int +} + +// SequenceMatcher compares sequence of strings. The basic +// algorithm predates, and is a little fancier than, an algorithm +// published in the late 1980's by Ratcliff and Obershelp under the +// hyperbolic name "gestalt pattern matching". The basic idea is to find +// the longest contiguous matching subsequence that contains no "junk" +// elements (R-O doesn't address junk). The same idea is then applied +// recursively to the pieces of the sequences to the left and to the right +// of the matching subsequence. This does not yield minimal edit +// sequences, but does tend to yield matches that "look right" to people. +// +// SequenceMatcher tries to compute a "human-friendly diff" between two +// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the +// longest *contiguous* & junk-free matching subsequence. That's what +// catches peoples' eyes. The Windows(tm) windiff has another interesting +// notion, pairing up elements that appear uniquely in each sequence. +// That, and the method here, appear to yield more intuitive difference +// reports than does diff. This method appears to be the least vulnerable +// to synching up on blocks of "junk lines", though (like blank lines in +// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +func NewMatcherWithJunk(a, b []string, autoJunk bool, + isJunk func(string) bool, +) *SequenceMatcher { + m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// and for all (i',j',k') meeting those conditions, +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize++ + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize++ + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{ + c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n), + }) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Return a measure of the sequences' similarity (float in [0,1]). +// +// Where T is the total number of elements in both sequences, and +// M is the number of matches, this is 2.0*M / T. +// Note that this is 1 if the sequences are identical, and 0 if +// they have nothing in common. +// +// .Ratio() is expensive to compute if you haven't already computed +// .GetMatchingBlocks() or .GetOpCodes(), in which case you may +// want to try .QuickRatio() or .RealQuickRation() first to get an +// upper bound. +func (m *SequenceMatcher) Ratio() float64 { + matches := 0 + for _, m := range m.GetMatchingBlocks() { + matches += m.Size + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() relatively quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute. +func (m *SequenceMatcher) QuickRatio() float64 { + // viewing a and b as multisets, set matches to the cardinality + // of their intersection; this counts the number of matches + // without regard to order, so is clearly an upper bound + if m.fullBCount == nil { + m.fullBCount = map[string]int{} + for _, s := range m.b { + m.fullBCount[s]++ + } + } + + // avail[x] is the number of times x appears in 'b' less the + // number of times we've seen it in 'a' so far ... kinda + avail := map[string]int{} + matches := 0 + for _, s := range m.a { + n, ok := avail[s] + if !ok { + n = m.fullBCount[s] + } + avail[s] = n - 1 + if n > 0 { + matches++ + } + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() very quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute than either .Ratio() or .QuickRatio(). +func (m *SequenceMatcher) RealQuickRatio() float64 { + la, lb := len(m.a), len(m.b) + return calculateRatio(min(la, lb), la+lb) +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning-- // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + wf := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := ws(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := ws("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := ws("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return w.String(), err +} + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" + return lines +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go new file mode 100644 index 000000000..723b45d64 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_collector_options.go @@ -0,0 +1,32 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package internal + +import "regexp" + +type GoCollectorRule struct { + Matcher *regexp.Regexp + Deny bool +} + +// GoCollectorOptions should not be used be directly by anything, except `collectors` package. +// Use it via collectors package instead. See issue +// https://github.com/prometheus/client_golang/issues/1030. +// +// This is internal, so external users only can use it via `collector.WithGoCollector*` methods +type GoCollectorOptions struct { + DisableMemStatsLikeMetrics bool + RuntimeMetricSumForHist map[string]string + RuntimeMetricRules []GoCollectorRule +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go index fe0a52180..97d17d6cb 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/go_runtime_metrics.go @@ -61,9 +61,9 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) // name has - replaced with _ and is concatenated with the unit and // other data. name = strings.ReplaceAll(name, "-", "_") - name = name + "_" + unit - if d.Cumulative { - name = name + "_total" + name += "_" + unit + if d.Cumulative && d.Kind != metrics.KindFloat64Histogram { + name += "_total" } valid := model.IsValidMetricName(model.LabelValue(namespace + "_" + subsystem + "_" + name)) @@ -84,12 +84,12 @@ func RuntimeMetricsToProm(d *metrics.Description) (string, string, string, bool) func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 { switch unit { case "bytes": - // Rebucket as powers of 2. - return rebucketExp(buckets, 2) + // Re-bucket as powers of 2. + return reBucketExp(buckets, 2) case "seconds": - // Rebucket as powers of 10 and then merge all buckets greater + // Re-bucket as powers of 10 and then merge all buckets greater // than 1 second into the +Inf bucket. - b := rebucketExp(buckets, 10) + b := reBucketExp(buckets, 10) for i := range b { if b[i] <= 1 { continue @@ -103,11 +103,11 @@ func RuntimeMetricsBucketsForUnit(buckets []float64, unit string) []float64 { return buckets } -// rebucketExp takes a list of bucket boundaries (lower bound inclusive) and +// reBucketExp takes a list of bucket boundaries (lower bound inclusive) and // downsamples the buckets to those a multiple of base apart. The end result // is a roughly exponential (in many cases, perfectly exponential) bucketing // scheme. -func rebucketExp(buckets []float64, base float64) []float64 { +func reBucketExp(buckets []float64, base float64) []float64 { bucket := buckets[0] var newBuckets []float64 // We may see a -Inf here, in which case, add it and skip it diff --git a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go index 351c26e1a..6515c1148 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/internal/metric.go @@ -19,18 +19,34 @@ import ( dto "github.com/prometheus/client_model/go" ) -// metricSorter is a sortable slice of *dto.Metric. -type metricSorter []*dto.Metric +// LabelPairSorter implements sort.Interface. It is used to sort a slice of +// dto.LabelPair pointers. +type LabelPairSorter []*dto.LabelPair -func (s metricSorter) Len() int { +func (s LabelPairSorter) Len() int { return len(s) } -func (s metricSorter) Swap(i, j int) { +func (s LabelPairSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s metricSorter) Less(i, j int) bool { +func (s LabelPairSorter) Less(i, j int) bool { + return s[i].GetName() < s[j].GetName() +} + +// MetricSorter is a sortable slice of *dto.Metric. +type MetricSorter []*dto.Metric + +func (s MetricSorter) Len() int { + return len(s) +} + +func (s MetricSorter) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s MetricSorter) Less(i, j int) bool { if len(s[i].Label) != len(s[j].Label) { // This should not happen. The metrics are // inconsistent. However, we have to deal with the fact, as @@ -68,7 +84,7 @@ func (s metricSorter) Less(i, j int) bool { // the slice, with the contained Metrics sorted within each MetricFamily. func NormalizeMetricFamilies(metricFamiliesByName map[string]*dto.MetricFamily) []*dto.MetricFamily { for _, mf := range metricFamiliesByName { - sort.Sort(metricSorter(mf.Metric)) + sort.Sort(MetricSorter(mf.Metric)) } names := make([]string, 0, len(metricFamiliesByName)) for name, mf := range metricFamiliesByName { diff --git a/vendor/github.com/prometheus/client_golang/prometheus/labels.go b/vendor/github.com/prometheus/client_golang/prometheus/labels.go index 2744443ac..6eee198fe 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/labels.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/labels.go @@ -39,7 +39,7 @@ var errInconsistentCardinality = errors.New("inconsistent label cardinality") func makeInconsistentCardinalityError(fqName string, labels, labelValues []string) error { return fmt.Errorf( - "%s: %q has %d variable labels named %q but %d values %q were provided", + "%w: %q has %d variable labels named %q but %d values %q were provided", errInconsistentCardinality, fqName, len(labels), labels, len(labelValues), labelValues, @@ -49,7 +49,7 @@ func makeInconsistentCardinalityError(fqName string, labels, labelValues []strin func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error { if len(labels) != expectedNumberOfValues { return fmt.Errorf( - "%s: expected %d label values but got %d in %#v", + "%w: expected %d label values but got %d in %#v", errInconsistentCardinality, expectedNumberOfValues, len(labels), labels, ) @@ -67,7 +67,7 @@ func validateValuesInLabels(labels Labels, expectedNumberOfValues int) error { func validateLabelValues(vals []string, expectedNumberOfValues int) error { if len(vals) != expectedNumberOfValues { return fmt.Errorf( - "%s: expected %d label values but got %d in %#v", + "%w: expected %d label values but got %d in %#v", errInconsistentCardinality, expectedNumberOfValues, len(vals), vals, ) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/metric.go b/vendor/github.com/prometheus/client_golang/prometheus/metric.go index dc121910a..f0941f6f0 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/metric.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/metric.go @@ -14,6 +14,9 @@ package prometheus import ( + "errors" + "math" + "sort" "strings" "time" @@ -115,22 +118,6 @@ func BuildFQName(namespace, subsystem, name string) string { return name } -// labelPairSorter implements sort.Interface. It is used to sort a slice of -// dto.LabelPair pointers. -type labelPairSorter []*dto.LabelPair - -func (s labelPairSorter) Len() int { - return len(s) -} - -func (s labelPairSorter) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (s labelPairSorter) Less(i, j int) bool { - return s[i].GetName() < s[j].GetName() -} - type invalidMetric struct { desc *Desc err error @@ -174,3 +161,96 @@ func (m timestampedMetric) Write(pb *dto.Metric) error { func NewMetricWithTimestamp(t time.Time, m Metric) Metric { return timestampedMetric{Metric: m, t: t} } + +type withExemplarsMetric struct { + Metric + + exemplars []*dto.Exemplar +} + +func (m *withExemplarsMetric) Write(pb *dto.Metric) error { + if err := m.Metric.Write(pb); err != nil { + return err + } + + switch { + case pb.Counter != nil: + pb.Counter.Exemplar = m.exemplars[len(m.exemplars)-1] + case pb.Histogram != nil: + for _, e := range m.exemplars { + // pb.Histogram.Bucket are sorted by UpperBound. + i := sort.Search(len(pb.Histogram.Bucket), func(i int) bool { + return pb.Histogram.Bucket[i].GetUpperBound() >= e.GetValue() + }) + if i < len(pb.Histogram.Bucket) { + pb.Histogram.Bucket[i].Exemplar = e + } else { + // The +Inf bucket should be explicitly added if there is an exemplar for it, similar to non-const histogram logic in https://github.com/prometheus/client_golang/blob/main/prometheus/histogram.go#L357-L365. + b := &dto.Bucket{ + CumulativeCount: proto.Uint64(pb.Histogram.Bucket[len(pb.Histogram.GetBucket())-1].GetCumulativeCount()), + UpperBound: proto.Float64(math.Inf(1)), + Exemplar: e, + } + pb.Histogram.Bucket = append(pb.Histogram.Bucket, b) + } + } + default: + // TODO(bwplotka): Implement Gauge? + return errors.New("cannot inject exemplar into Gauge, Summary or Untyped") + } + + return nil +} + +// Exemplar is easier to use, user-facing representation of *dto.Exemplar. +type Exemplar struct { + Value float64 + Labels Labels + // Optional. + // Default value (time.Time{}) indicates its empty, which should be + // understood as time.Now() time at the moment of creation of metric. + Timestamp time.Time +} + +// NewMetricWithExemplars returns a new Metric wrapping the provided Metric with given +// exemplars. Exemplars are validated. +// +// Only last applicable exemplar is injected from the list. +// For example for Counter it means last exemplar is injected. +// For Histogram, it means last applicable exemplar for each bucket is injected. +// +// NewMetricWithExemplars works best with MustNewConstMetric and +// MustNewConstHistogram, see example. +func NewMetricWithExemplars(m Metric, exemplars ...Exemplar) (Metric, error) { + if len(exemplars) == 0 { + return nil, errors.New("no exemplar was passed for NewMetricWithExemplars") + } + + var ( + now = time.Now() + exs = make([]*dto.Exemplar, len(exemplars)) + err error + ) + for i, e := range exemplars { + ts := e.Timestamp + if ts == (time.Time{}) { + ts = now + } + exs[i], err = newExemplar(e.Value, ts, e.Labels) + if err != nil { + return nil, err + } + } + + return &withExemplarsMetric{Metric: m, exemplars: exs}, nil +} + +// MustNewMetricWithExemplars is a version of NewMetricWithExemplars that panics where +// NewMetricWithExemplars would have returned an error. +func MustNewMetricWithExemplars(m Metric, exemplars ...Exemplar) Metric { + ret, err := NewMetricWithExemplars(m, exemplars...) + if err != nil { + panic(err) + } + return ret +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go new file mode 100644 index 000000000..7c12b2108 --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/num_threads.go @@ -0,0 +1,25 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !js || wasm +// +build !js wasm + +package prometheus + +import "runtime" + +// getRuntimeNumThreads returns the number of open OS threads. +func getRuntimeNumThreads() float64 { + n, _ := runtime.ThreadCreateProfile(nil) + return float64(n) +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go b/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go new file mode 100644 index 000000000..7348df01d --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/num_threads_gopherjs.go @@ -0,0 +1,22 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build js && !wasm +// +build js,!wasm + +package prometheus + +// getRuntimeNumThreads returns the number of open OS threads. +func getRuntimeNumThreads() float64 { + return 1 +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/observer.go b/vendor/github.com/prometheus/client_golang/prometheus/observer.go index 44128016f..03773b21f 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/observer.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/observer.go @@ -58,7 +58,7 @@ type ObserverVec interface { // current time as timestamp, and the provided Labels. Empty Labels will lead to // a valid (label-less) exemplar. But if Labels is nil, the current exemplar is // left in place. ObserveWithExemplar panics if any of the provided labels are -// invalid or if the provided labels contain more than 64 runes in total. +// invalid or if the provided labels contain more than 128 runes in total. type ExemplarObserver interface { ObserveWithExemplar(value float64, exemplar Labels) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go index 5bfe0ff5b..8548dd18e 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector.go @@ -16,7 +16,6 @@ package prometheus import ( "errors" "fmt" - "io/ioutil" "os" "strconv" "strings" @@ -104,8 +103,7 @@ func NewProcessCollector(opts ProcessCollectorOpts) Collector { } if opts.PidFn == nil { - pid := os.Getpid() - c.pidFn = func() (int, error) { return pid, nil } + c.pidFn = getPIDFn() } else { c.pidFn = opts.PidFn } @@ -152,13 +150,13 @@ func (c *processCollector) reportError(ch chan<- Metric, desc *Desc, err error) // It is meant to be used for the PidFn field in ProcessCollectorOpts. func NewPidFileFn(pidFilePath string) func() (int, error) { return func() (int, error) { - content, err := ioutil.ReadFile(pidFilePath) + content, err := os.ReadFile(pidFilePath) if err != nil { - return 0, fmt.Errorf("can't read pid file %q: %+v", pidFilePath, err) + return 0, fmt.Errorf("can't read pid file %q: %w", pidFilePath, err) } pid, err := strconv.Atoi(strings.TrimSpace(string(content))) if err != nil { - return 0, fmt.Errorf("can't parse pid file %q: %+v", pidFilePath, err) + return 0, fmt.Errorf("can't parse pid file %q: %w", pidFilePath, err) } return pid, nil diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go new file mode 100644 index 000000000..b1e363d6c --- /dev/null +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_js.go @@ -0,0 +1,26 @@ +// Copyright 2019 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build js +// +build js + +package prometheus + +func canCollectProcess() bool { + return false +} + +func (c *processCollector) processCollect(ch chan<- Metric) { + // noop on this platform + return +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go index 2dc3660da..c0152cdb6 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/process_collector_other.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !windows -// +build !windows +//go:build !windows && !js +// +build !windows,!js package prometheus diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go index e7c0d0546..9819917b8 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/delegator.go @@ -76,16 +76,19 @@ func (r *responseWriterDelegator) Write(b []byte) (int, error) { return n, err } -type closeNotifierDelegator struct{ *responseWriterDelegator } -type flusherDelegator struct{ *responseWriterDelegator } -type hijackerDelegator struct{ *responseWriterDelegator } -type readerFromDelegator struct{ *responseWriterDelegator } -type pusherDelegator struct{ *responseWriterDelegator } +type ( + closeNotifierDelegator struct{ *responseWriterDelegator } + flusherDelegator struct{ *responseWriterDelegator } + hijackerDelegator struct{ *responseWriterDelegator } + readerFromDelegator struct{ *responseWriterDelegator } + pusherDelegator struct{ *responseWriterDelegator } +) func (d closeNotifierDelegator) CloseNotify() <-chan bool { //nolint:staticcheck // Ignore SA1019. http.CloseNotifier is deprecated but we keep it here to not break existing users. return d.ResponseWriter.(http.CloseNotifier).CloseNotify() } + func (d flusherDelegator) Flush() { // If applicable, call WriteHeader here so that observeWriteHeader is // handled appropriately. @@ -94,9 +97,11 @@ func (d flusherDelegator) Flush() { } d.ResponseWriter.(http.Flusher).Flush() } + func (d hijackerDelegator) Hijack() (net.Conn, *bufio.ReadWriter, error) { return d.ResponseWriter.(http.Hijacker).Hijack() } + func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) { // If applicable, call WriteHeader here so that observeWriteHeader is // handled appropriately. @@ -107,6 +112,7 @@ func (d readerFromDelegator) ReadFrom(re io.Reader) (int64, error) { d.written += n return n, err } + func (d pusherDelegator) Push(target string, opts *http.PushOptions) error { return d.ResponseWriter.(http.Pusher).Push(target, opts) } @@ -261,7 +267,7 @@ func init() { http.Flusher }{d, pusherDelegator{d}, hijackerDelegator{d}, flusherDelegator{d}} } - pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { //23 + pickDelegator[pusher+hijacker+flusher+closeNotifier] = func(d *responseWriterDelegator) delegator { // 23 return struct { *responseWriterDelegator http.Pusher diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go index d86d0cf4b..a4cc9810b 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/http.go @@ -33,6 +33,7 @@ package promhttp import ( "compress/gzip" + "errors" "fmt" "io" "net/http" @@ -84,6 +85,13 @@ func Handler() http.Handler { // instrumentation. Use the InstrumentMetricHandler function to apply the same // kind of instrumentation as it is used by the Handler function. func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { + return HandlerForTransactional(prometheus.ToTransactionalGatherer(reg), opts) +} + +// HandlerForTransactional is like HandlerFor, but it uses transactional gather, which +// can safely change in-place returned *dto.MetricFamily before call to `Gather` and after +// call to `done` of that `Gather`. +func HandlerForTransactional(reg prometheus.TransactionalGatherer, opts HandlerOpts) http.Handler { var ( inFlightSem chan struct{} errCnt = prometheus.NewCounterVec( @@ -103,7 +111,8 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { errCnt.WithLabelValues("gathering") errCnt.WithLabelValues("encoding") if err := opts.Registry.Register(errCnt); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { + are := &prometheus.AlreadyRegisteredError{} + if errors.As(err, are) { errCnt = are.ExistingCollector.(*prometheus.CounterVec) } else { panic(err) @@ -123,7 +132,8 @@ func HandlerFor(reg prometheus.Gatherer, opts HandlerOpts) http.Handler { return } } - mfs, err := reg.Gather() + mfs, done, err := reg.Gather() + defer done() if err != nil { if opts.ErrorLog != nil { opts.ErrorLog.Println("error gathering metrics:", err) @@ -242,7 +252,8 @@ func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) ht cnt.WithLabelValues("500") cnt.WithLabelValues("503") if err := reg.Register(cnt); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { + are := &prometheus.AlreadyRegisteredError{} + if errors.As(err, are) { cnt = are.ExistingCollector.(*prometheus.CounterVec) } else { panic(err) @@ -254,7 +265,8 @@ func InstrumentMetricHandler(reg prometheus.Registerer, handler http.Handler) ht Help: "Current number of scrapes being served.", }) if err := reg.Register(gge); err != nil { - if are, ok := err.(prometheus.AlreadyRegisteredError); ok { + are := &prometheus.AlreadyRegisteredError{} + if errors.As(err, are) { gge = are.ExistingCollector.(prometheus.Gauge) } else { panic(err) diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go index 861b4d21c..097aff2df 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go @@ -38,11 +38,11 @@ func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { // // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripper) RoundTripperFunc { - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { gauge.Inc() defer gauge.Dec() return next.RoundTrip(r) - }) + } } // InstrumentRoundTripperCounter is a middleware that wraps the provided @@ -59,22 +59,29 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp // If the wrapped RoundTripper panics or returns a non-nil error, the Counter // is not incremented. // +// Use with WithExemplarFromContext to instrument the exemplars on the counter of requests. +// // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc { - rtOpts := &option{} + rtOpts := defaultOptions() for _, o := range opts { - o(rtOpts) + o.apply(rtOpts) } code, method := checkLabels(counter) - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { resp, err := next.RoundTrip(r) if err == nil { + exemplarAdd( + counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), + 1, + rtOpts.getExemplarFn(r.Context()), + ) counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Inc() } return resp, err - }) + } } // InstrumentRoundTripperDuration is a middleware that wraps the provided @@ -94,24 +101,30 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou // If the wrapped RoundTripper panics or returns a non-nil error, no values are // reported. // +// Use with WithExemplarFromContext to instrument the exemplars on the duration histograms. +// // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc { - rtOpts := &option{} + rtOpts := defaultOptions() for _, o := range opts { - o(rtOpts) + o.apply(rtOpts) } code, method := checkLabels(obs) - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { start := time.Now() resp, err := next.RoundTrip(r) if err == nil { - obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Observe(time.Since(start).Seconds()) + exemplarObserve( + obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)), + time.Since(start).Seconds(), + rtOpts.getExemplarFn(r.Context()), + ) } return resp, err - }) + } } // InstrumentTrace is used to offer flexibility in instrumenting the available @@ -149,7 +162,7 @@ type InstrumentTrace struct { // // See the example for ExampleInstrumentRoundTripperDuration for example usage. func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) RoundTripperFunc { - return RoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return func(r *http.Request) (*http.Response, error) { start := time.Now() trace := &httptrace.ClientTrace{ @@ -231,5 +244,5 @@ func InstrumentRoundTripperTrace(it *InstrumentTrace, next http.RoundTripper) Ro r = r.WithContext(httptrace.WithClientTrace(r.Context(), trace)) return next.RoundTrip(r) - }) + } } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go index a23f0edc6..bfe500987 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go @@ -28,6 +28,22 @@ import ( // magicString is used for the hacky label test in checkLabels. Remove once fixed. const magicString = "zZgWfBxLqvG8kc8IMv3POi2Bb0tZI3vAnBx+gBaFi9FyPzB/CzKUer1yufDa" +func exemplarObserve(obs prometheus.Observer, val float64, labels map[string]string) { + if labels == nil { + obs.Observe(val) + return + } + obs.(prometheus.ExemplarObserver).ObserveWithExemplar(val, labels) +} + +func exemplarAdd(obs prometheus.Counter, val float64, labels map[string]string) { + if labels == nil { + obs.Add(val) + return + } + obs.(prometheus.ExemplarAdder).AddWithExemplar(val, labels) +} + // InstrumentHandlerInFlight is a middleware that wraps the provided // http.Handler. It sets the provided prometheus.Gauge to the number of // requests currently handled by the wrapped http.Handler. @@ -48,7 +64,7 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl // names are "code" and "method". The function panics otherwise. For the "method" // label a predefined default label value set is used to filter given values. // Values besides predefined values will count as `unknown` method. -//`WithExtraMethods` can be used to add more methods to the set. The Observe +// `WithExtraMethods` can be used to add more methods to the set. The Observe // method of the Observer in the ObserverVec is called with the request duration // in seconds. Partitioning happens by HTTP status code and/or HTTP method if // the respective instance label names are present in the ObserverVec. For @@ -62,28 +78,37 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl // Note that this method is only guaranteed to never observe negative durations // if used with Go1.9+. func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) if code { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { now := time.Now() d := newDelegator(w, nil) next.ServeHTTP(d, r) - obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(time.Since(now).Seconds()) - }) + exemplarObserve( + obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + time.Since(now).Seconds(), + hOpts.getExemplarFn(r.Context()), + ) + } } - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { now := time.Now() next.ServeHTTP(w, r) - obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds()) - }) + + exemplarObserve( + obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), + time.Since(now).Seconds(), + hOpts.getExemplarFn(r.Context()), + ) + } } // InstrumentHandlerCounter is a middleware that wraps the provided http.Handler @@ -104,25 +129,34 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, op // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(counter) if code { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) - counter.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Inc() - }) + + exemplarAdd( + counter.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + 1, + hOpts.getExemplarFn(r.Context()), + ) + } } - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) - counter.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Inc() - }) + exemplarAdd( + counter.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), + 1, + hOpts.getExemplarFn(r.Context()), + ) + } } // InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided @@ -148,20 +182,24 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { now := time.Now() d := newDelegator(w, func(status int) { - obs.With(labels(code, method, r.Method, status, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds()) + exemplarObserve( + obs.With(labels(code, method, r.Method, status, hOpts.extraMethods...)), + time.Since(now).Seconds(), + hOpts.getExemplarFn(r.Context()), + ) }) next.ServeHTTP(d, r) - }) + } } // InstrumentHandlerRequestSize is a middleware that wraps the provided @@ -184,27 +222,34 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) - if code { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) size := computeApproximateRequestSize(r) - obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(size)) - }) + exemplarObserve( + obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + float64(size), + hOpts.getExemplarFn(r.Context()), + ) + } } - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { next.ServeHTTP(w, r) size := computeApproximateRequestSize(r) - obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(float64(size)) - }) + exemplarObserve( + obs.With(labels(code, method, r.Method, 0, hOpts.extraMethods...)), + float64(size), + hOpts.getExemplarFn(r.Context()), + ) + } } // InstrumentHandlerResponseSize is a middleware that wraps the provided @@ -227,9 +272,9 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, // // See the example for InstrumentHandlerDuration for example usage. func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler { - mwOpts := &option{} + hOpts := defaultOptions() for _, o := range opts { - o(mwOpts) + o.apply(hOpts) } code, method := checkLabels(obs) @@ -237,7 +282,11 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { d := newDelegator(w, nil) next.ServeHTTP(d, r) - obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(d.Written())) + exemplarObserve( + obs.With(labels(code, method, r.Method, d.Status(), hOpts.extraMethods...)), + float64(d.Written()), + hOpts.getExemplarFn(r.Context()), + ) }) } @@ -246,7 +295,7 @@ func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler // Collector does not have a Desc or has more than one Desc or its Desc is // invalid. It also panics if the Collector has any non-const, non-curried // labels that are not named "code" or "method". -func checkLabels(c prometheus.Collector) (code bool, method bool) { +func checkLabels(c prometheus.Collector) (code, method bool) { // TODO(beorn7): Remove this hacky way to check for instance labels // once Descriptors can have their dimensionality queried. var ( diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go index 35e41bd1e..c590d912c 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go @@ -13,19 +13,46 @@ package promhttp -// Option are used to configure a middleware or round tripper.. -type Option func(*option) +import ( + "context" -type option struct { - extraMethods []string + "github.com/prometheus/client_golang/prometheus" +) + +// Option are used to configure both handler (middleware) or round tripper. +type Option interface { + apply(*options) } +// options store options for both a handler or round tripper. +type options struct { + extraMethods []string + getExemplarFn func(requestCtx context.Context) prometheus.Labels +} + +func defaultOptions() *options { + return &options{getExemplarFn: func(ctx context.Context) prometheus.Labels { return nil }} +} + +type optionApplyFunc func(*options) + +func (o optionApplyFunc) apply(opt *options) { o(opt) } + // WithExtraMethods adds additional HTTP methods to the list of allowed methods. // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list. // // See the example for ExampleInstrumentHandlerWithExtraMethods for example usage. func WithExtraMethods(methods ...string) Option { - return func(o *option) { + return optionApplyFunc(func(o *options) { o.extraMethods = methods - } + }) +} + +// WithExemplarFromContext adds allows to put a hook to all counter and histogram metrics. +// If the hook function returns non-nil labels, exemplars will be added for that request, otherwise metric +// will get instrumented without exemplar. +func WithExemplarFromContext(getExemplarFn func(requestCtx context.Context) prometheus.Labels) Option { + return optionApplyFunc(func(o *options) { + o.getExemplarFn = getExemplarFn + }) } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/registry.go b/vendor/github.com/prometheus/client_golang/prometheus/registry.go index 383a7f594..325f665ff 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/registry.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/registry.go @@ -15,8 +15,8 @@ package prometheus import ( "bytes" + "errors" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -289,7 +289,7 @@ func (r *Registry) Register(c Collector) error { // Is the descriptor valid at all? if desc.err != nil { - return fmt.Errorf("descriptor %s is invalid: %s", desc, desc.err) + return fmt.Errorf("descriptor %s is invalid: %w", desc, desc.err) } // Is the descID unique? @@ -407,6 +407,14 @@ func (r *Registry) MustRegister(cs ...Collector) { // Gather implements Gatherer. func (r *Registry) Gather() ([]*dto.MetricFamily, error) { + r.mtx.RLock() + + if len(r.collectorsByID) == 0 && len(r.uncheckedCollectors) == 0 { + // Fast path. + r.mtx.RUnlock() + return nil, nil + } + var ( checkedMetricChan = make(chan Metric, capMetricChan) uncheckedMetricChan = make(chan Metric, capMetricChan) @@ -416,7 +424,6 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { registeredDescIDs map[uint64]struct{} // Only used for pedantic checks ) - r.mtx.RLock() goroutineBudget := len(r.collectorsByID) + len(r.uncheckedCollectors) metricFamiliesByName := make(map[string]*dto.MetricFamily, len(r.dimHashesByName)) checkedCollectors := make(chan Collector, len(r.collectorsByID)) @@ -556,7 +563,7 @@ func (r *Registry) Gather() ([]*dto.MetricFamily, error) { // This is intended for use with the textfile collector of the node exporter. // Note that the node exporter expects the filename to be suffixed with ".prom". func WriteToTextfile(filename string, g Gatherer) error { - tmp, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)) + tmp, err := os.CreateTemp(filepath.Dir(filename), filepath.Base(filename)) if err != nil { return err } @@ -575,7 +582,7 @@ func WriteToTextfile(filename string, g Gatherer) error { return err } - if err := os.Chmod(tmp.Name(), 0644); err != nil { + if err := os.Chmod(tmp.Name(), 0o644); err != nil { return err } return os.Rename(tmp.Name(), filename) @@ -596,7 +603,7 @@ func processMetric( } dtoMetric := &dto.Metric{} if err := metric.Write(dtoMetric); err != nil { - return fmt.Errorf("error collecting metric %v: %s", desc, err) + return fmt.Errorf("error collecting metric %v: %w", desc, err) } metricFamily, ok := metricFamiliesByName[desc.fqName] if ok { // Existing name. @@ -718,12 +725,13 @@ func (gs Gatherers) Gather() ([]*dto.MetricFamily, error) { for i, g := range gs { mfs, err := g.Gather() if err != nil { - if multiErr, ok := err.(MultiError); ok { + multiErr := MultiError{} + if errors.As(err, &multiErr) { for _, err := range multiErr { - errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err)) + errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) } } else { - errs = append(errs, fmt.Errorf("[from Gatherer #%d] %s", i+1, err)) + errs = append(errs, fmt.Errorf("[from Gatherer #%d] %w", i+1, err)) } } for _, mf := range mfs { @@ -884,11 +892,11 @@ func checkMetricConsistency( h.Write(separatorByteSlice) // Make sure label pairs are sorted. We depend on it for the consistency // check. - if !sort.IsSorted(labelPairSorter(dtoMetric.Label)) { + if !sort.IsSorted(internal.LabelPairSorter(dtoMetric.Label)) { // We cannot sort dtoMetric.Label in place as it is immutable by contract. copiedLabels := make([]*dto.LabelPair, len(dtoMetric.Label)) copy(copiedLabels, dtoMetric.Label) - sort.Sort(labelPairSorter(copiedLabels)) + sort.Sort(internal.LabelPairSorter(copiedLabels)) dtoMetric.Label = copiedLabels } for _, lp := range dtoMetric.Label { @@ -935,7 +943,7 @@ func checkDescConsistency( metricFamily.GetName(), dtoMetric, desc, ) } - sort.Sort(labelPairSorter(lpsFromDesc)) + sort.Sort(internal.LabelPairSorter(lpsFromDesc)) for i, lpFromDesc := range lpsFromDesc { lpFromMetric := dtoMetric.Label[i] if lpFromDesc.GetName() != lpFromMetric.GetName() || @@ -948,3 +956,89 @@ func checkDescConsistency( } return nil } + +var _ TransactionalGatherer = &MultiTRegistry{} + +// MultiTRegistry is a TransactionalGatherer that joins gathered metrics from multiple +// transactional gatherers. +// +// It is caller responsibility to ensure two registries have mutually exclusive metric families, +// no deduplication will happen. +type MultiTRegistry struct { + tGatherers []TransactionalGatherer +} + +// NewMultiTRegistry creates MultiTRegistry. +func NewMultiTRegistry(tGatherers ...TransactionalGatherer) *MultiTRegistry { + return &MultiTRegistry{ + tGatherers: tGatherers, + } +} + +// Gather implements TransactionalGatherer interface. +func (r *MultiTRegistry) Gather() (mfs []*dto.MetricFamily, done func(), err error) { + errs := MultiError{} + + dFns := make([]func(), 0, len(r.tGatherers)) + // TODO(bwplotka): Implement concurrency for those? + for _, g := range r.tGatherers { + // TODO(bwplotka): Check for duplicates? + m, d, err := g.Gather() + errs.Append(err) + + mfs = append(mfs, m...) + dFns = append(dFns, d) + } + + // TODO(bwplotka): Consider sort in place, given metric family in gather is sorted already. + sort.Slice(mfs, func(i, j int) bool { + return *mfs[i].Name < *mfs[j].Name + }) + return mfs, func() { + for _, d := range dFns { + d() + } + }, errs.MaybeUnwrap() +} + +// TransactionalGatherer represents transactional gatherer that can be triggered to notify gatherer that memory +// used by metric family is no longer used by a caller. This allows implementations with cache. +type TransactionalGatherer interface { + // Gather returns metrics in a lexicographically sorted slice + // of uniquely named MetricFamily protobufs. Gather ensures that the + // returned slice is valid and self-consistent so that it can be used + // for valid exposition. As an exception to the strict consistency + // requirements described for metric.Desc, Gather will tolerate + // different sets of label names for metrics of the same metric family. + // + // Even if an error occurs, Gather attempts to gather as many metrics as + // possible. Hence, if a non-nil error is returned, the returned + // MetricFamily slice could be nil (in case of a fatal error that + // prevented any meaningful metric collection) or contain a number of + // MetricFamily protobufs, some of which might be incomplete, and some + // might be missing altogether. The returned error (which might be a + // MultiError) explains the details. Note that this is mostly useful for + // debugging purposes. If the gathered protobufs are to be used for + // exposition in actual monitoring, it is almost always better to not + // expose an incomplete result and instead disregard the returned + // MetricFamily protobufs in case the returned error is non-nil. + // + // Important: done is expected to be triggered (even if the error occurs!) + // once caller does not need returned slice of dto.MetricFamily. + Gather() (_ []*dto.MetricFamily, done func(), err error) +} + +// ToTransactionalGatherer transforms Gatherer to transactional one with noop as done function. +func ToTransactionalGatherer(g Gatherer) TransactionalGatherer { + return &noTransactionGatherer{g: g} +} + +type noTransactionGatherer struct { + g Gatherer +} + +// Gather implements TransactionalGatherer interface. +func (g *noTransactionGatherer) Gather() (_ []*dto.MetricFamily, done func(), err error) { + mfs, err := g.g.Gather() + return mfs, func() {}, err +} diff --git a/vendor/github.com/prometheus/client_golang/prometheus/value.go b/vendor/github.com/prometheus/client_golang/prometheus/value.go index b4e0ae11c..2d3abc1cb 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/value.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/value.go @@ -23,6 +23,8 @@ import ( "github.com/golang/protobuf/proto" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/prometheus/client_golang/prometheus/internal" + dto "github.com/prometheus/client_model/go" ) @@ -38,6 +40,23 @@ const ( UntypedValue ) +var ( + CounterMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_COUNTER; return &d }() + GaugeMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_GAUGE; return &d }() + UntypedMetricTypePtr = func() *dto.MetricType { d := dto.MetricType_UNTYPED; return &d }() +) + +func (v ValueType) ToDTO() *dto.MetricType { + switch v { + case CounterValue: + return CounterMetricTypePtr + case GaugeValue: + return GaugeMetricTypePtr + default: + return UntypedMetricTypePtr + } +} + // valueFunc is a generic metric for simple values retrieved on collect time // from a function. It implements Metric and Collector. Its effective type is // determined by ValueType. This is a low-level building block used by the @@ -91,11 +110,15 @@ func NewConstMetric(desc *Desc, valueType ValueType, value float64, labelValues if err := validateLabelValues(labelValues, len(desc.variableLabels)); err != nil { return nil, err } + + metric := &dto.Metric{} + if err := populateMetric(valueType, value, MakeLabelPairs(desc, labelValues), nil, metric); err != nil { + return nil, err + } + return &constMetric{ - desc: desc, - valType: valueType, - val: value, - labelPairs: MakeLabelPairs(desc, labelValues), + desc: desc, + metric: metric, }, nil } @@ -110,10 +133,8 @@ func MustNewConstMetric(desc *Desc, valueType ValueType, value float64, labelVal } type constMetric struct { - desc *Desc - valType ValueType - val float64 - labelPairs []*dto.LabelPair + desc *Desc + metric *dto.Metric } func (m *constMetric) Desc() *Desc { @@ -121,7 +142,11 @@ func (m *constMetric) Desc() *Desc { } func (m *constMetric) Write(out *dto.Metric) error { - return populateMetric(m.valType, m.val, m.labelPairs, nil, out) + out.Label = m.metric.Label + out.Counter = m.metric.Counter + out.Gauge = m.metric.Gauge + out.Untyped = m.metric.Untyped + return nil } func populateMetric( @@ -170,12 +195,12 @@ func MakeLabelPairs(desc *Desc, labelValues []string) []*dto.LabelPair { }) } labelPairs = append(labelPairs, desc.constLabelPairs...) - sort.Sort(labelPairSorter(labelPairs)) + sort.Sort(internal.LabelPairSorter(labelPairs)) return labelPairs } // ExemplarMaxRunes is the max total number of runes allowed in exemplar labels. -const ExemplarMaxRunes = 64 +const ExemplarMaxRunes = 128 // newExemplar creates a new dto.Exemplar from the provided values. An error is // returned if any of the label names or values are invalid or if the total diff --git a/vendor/github.com/prometheus/client_golang/prometheus/vec.go b/vendor/github.com/prometheus/client_golang/prometheus/vec.go index 4ababe6c9..7ae322590 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/vec.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/vec.go @@ -99,6 +99,16 @@ func (m *MetricVec) Delete(labels Labels) bool { return m.metricMap.deleteByHashWithLabels(h, labels, m.curry) } +// DeletePartialMatch deletes all metrics where the variable labels contain all of those +// passed in as labels. The order of the labels does not matter. +// It returns the number of metrics deleted. +// +// Note that curried labels will never be matched if deleting from the curried vector. +// To match curried labels with DeletePartialMatch, it must be called on the base vector. +func (m *MetricVec) DeletePartialMatch(labels Labels) int { + return m.metricMap.deleteByLabels(labels, m.curry) +} + // Without explicit forwarding of Describe, Collect, Reset, those methods won't // show up in GoDoc. @@ -381,6 +391,82 @@ func (m *metricMap) deleteByHashWithLabels( return true } +// deleteByLabels deletes a metric if the given labels are present in the metric. +func (m *metricMap) deleteByLabels(labels Labels, curry []curriedLabelValue) int { + m.mtx.Lock() + defer m.mtx.Unlock() + + var numDeleted int + + for h, metrics := range m.metrics { + i := findMetricWithPartialLabels(m.desc, metrics, labels, curry) + if i >= len(metrics) { + // Didn't find matching labels in this metric slice. + continue + } + delete(m.metrics, h) + numDeleted++ + } + + return numDeleted +} + +// findMetricWithPartialLabel returns the index of the matching metric or +// len(metrics) if not found. +func findMetricWithPartialLabels( + desc *Desc, metrics []metricWithLabelValues, labels Labels, curry []curriedLabelValue, +) int { + for i, metric := range metrics { + if matchPartialLabels(desc, metric.values, labels, curry) { + return i + } + } + return len(metrics) +} + +// indexOf searches the given slice of strings for the target string and returns +// the index or len(items) as well as a boolean whether the search succeeded. +func indexOf(target string, items []string) (int, bool) { + for i, l := range items { + if l == target { + return i, true + } + } + return len(items), false +} + +// valueMatchesVariableOrCurriedValue determines if a value was previously curried, +// and returns whether it matches either the "base" value or the curried value accordingly. +// It also indicates whether the match is against a curried or uncurried value. +func valueMatchesVariableOrCurriedValue(targetValue string, index int, values []string, curry []curriedLabelValue) (bool, bool) { + for _, curriedValue := range curry { + if curriedValue.index == index { + // This label was curried. See if the curried value matches our target. + return curriedValue.value == targetValue, true + } + } + // This label was not curried. See if the current value matches our target label. + return values[index] == targetValue, false +} + +// matchPartialLabels searches the current metric and returns whether all of the target label:value pairs are present. +func matchPartialLabels(desc *Desc, values []string, labels Labels, curry []curriedLabelValue) bool { + for l, v := range labels { + // Check if the target label exists in our metrics and get the index. + varLabelIndex, validLabel := indexOf(l, desc.variableLabels) + if validLabel { + // Check the value of that label against the target value. + // We don't consider curried values in partial matches. + matches, curried := valueMatchesVariableOrCurriedValue(v, varLabelIndex, values, curry) + if matches && !curried { + continue + } + } + return false + } + return true +} + // getOrCreateMetricWithLabelValues retrieves the metric by hash and label value // or creates it and returns the new one. // @@ -485,7 +571,7 @@ func findMetricWithLabels( return len(metrics) } -func matchLabelValues(values []string, lvs []string, curry []curriedLabelValue) bool { +func matchLabelValues(values, lvs []string, curry []curriedLabelValue) bool { if len(values) != len(lvs)+len(curry) { return false } diff --git a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go index 74ee93280..1498ee144 100644 --- a/vendor/github.com/prometheus/client_golang/prometheus/wrap.go +++ b/vendor/github.com/prometheus/client_golang/prometheus/wrap.go @@ -21,6 +21,8 @@ import ( "github.com/golang/protobuf/proto" dto "github.com/prometheus/client_model/go" + + "github.com/prometheus/client_golang/prometheus/internal" ) // WrapRegistererWith returns a Registerer wrapping the provided @@ -182,7 +184,7 @@ func (m *wrappingMetric) Write(out *dto.Metric) error { Value: proto.String(lv), }) } - sort.Sort(labelPairSorter(out.Label)) + sort.Sort(internal.LabelPairSorter(out.Label)) return nil } diff --git a/vendor/github.com/prometheus/procfs/.gitignore b/vendor/github.com/prometheus/procfs/.gitignore index 25e3659ab..7cc33ae4a 100644 --- a/vendor/github.com/prometheus/procfs/.gitignore +++ b/vendor/github.com/prometheus/procfs/.gitignore @@ -1 +1,2 @@ -/fixtures/ +/testdata/fixtures/ +/fixtures diff --git a/vendor/github.com/prometheus/procfs/.golangci.yml b/vendor/github.com/prometheus/procfs/.golangci.yml index 0aa09edac..a197699a1 100644 --- a/vendor/github.com/prometheus/procfs/.golangci.yml +++ b/vendor/github.com/prometheus/procfs/.golangci.yml @@ -1,4 +1,12 @@ --- linters: enable: - - golint + - godot + - revive + +linter-settings: + godot: + capital: true + exclude: + # Ignore "See: URL" + - 'See:' diff --git a/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md b/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md index 9a1aff412..d325872bd 100644 --- a/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md +++ b/vendor/github.com/prometheus/procfs/CODE_OF_CONDUCT.md @@ -1,3 +1,3 @@ -## Prometheus Community Code of Conduct +# Prometheus Community Code of Conduct -Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). +Prometheus follows the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/main/code-of-conduct.md). diff --git a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md b/vendor/github.com/prometheus/procfs/CONTRIBUTING.md index 943de7615..853eb9d49 100644 --- a/vendor/github.com/prometheus/procfs/CONTRIBUTING.md +++ b/vendor/github.com/prometheus/procfs/CONTRIBUTING.md @@ -97,7 +97,7 @@ Many of the files are changing continuously and the data being read can in some reads in the same file. Also, most of the files are relatively small (less than a few KBs), and system calls to the `stat` function will often return the wrong size. Therefore, for most files it's recommended to read the full file in a single operation using an internal utility function called `util.ReadFileNoStat`. -This function is similar to `ioutil.ReadFile`, but it avoids the system call to `stat` to get the current size of +This function is similar to `os.ReadFile`, but it avoids the system call to `stat` to get the current size of the file. Note that parsing the file's contents can still be performed one line at a time. This is done by first reading @@ -113,7 +113,7 @@ the full file, and then using a scanner on the `[]byte` or `string` containing t ``` The `/sys` filesystem contains many very small files which contain only a single numeric or text value. These files -can be read using an internal function called `util.SysReadFile` which is similar to `ioutil.ReadFile` but does +can be read using an internal function called `util.SysReadFile` which is similar to `os.ReadFile` but does not bother to check the size of the file before reading. ``` data, err := util.SysReadFile("/sys/class/power_supply/BAT0/capacity") diff --git a/vendor/github.com/prometheus/procfs/Makefile b/vendor/github.com/prometheus/procfs/Makefile index fa2bd5b52..7edfe4d09 100644 --- a/vendor/github.com/prometheus/procfs/Makefile +++ b/vendor/github.com/prometheus/procfs/Makefile @@ -14,18 +14,18 @@ include Makefile.common %/.unpacked: %.ttar - @echo ">> extracting fixtures" + @echo ">> extracting fixtures $*" ./ttar -C $(dir $*) -x -f $*.ttar touch $@ -fixtures: fixtures/.unpacked +fixtures: testdata/fixtures/.unpacked update_fixtures: - rm -vf fixtures/.unpacked - ./ttar -c -f fixtures.ttar fixtures/ + rm -vf testdata/fixtures/.unpacked + ./ttar -c -f testdata/fixtures.ttar -C testdata/ fixtures/ .PHONY: build build: .PHONY: test -test: fixtures/.unpacked common-test +test: testdata/fixtures/.unpacked common-test diff --git a/vendor/github.com/prometheus/procfs/Makefile.common b/vendor/github.com/prometheus/procfs/Makefile.common index a1b1ca40f..6c8e3e219 100644 --- a/vendor/github.com/prometheus/procfs/Makefile.common +++ b/vendor/github.com/prometheus/procfs/Makefile.common @@ -36,29 +36,6 @@ GO_VERSION ?= $(shell $(GO) version) GO_VERSION_NUMBER ?= $(word 3, $(GO_VERSION)) PRE_GO_111 ?= $(shell echo $(GO_VERSION_NUMBER) | grep -E 'go1\.(10|[0-9])\.') -GOVENDOR := -GO111MODULE := -ifeq (, $(PRE_GO_111)) - ifneq (,$(wildcard go.mod)) - # Enforce Go modules support just in case the directory is inside GOPATH (and for Travis CI). - GO111MODULE := on - - ifneq (,$(wildcard vendor)) - # Always use the local vendor/ directory to satisfy the dependencies. - GOOPTS := $(GOOPTS) -mod=vendor - endif - endif -else - ifneq (,$(wildcard go.mod)) - ifneq (,$(wildcard vendor)) -$(warning This repository requires Go >= 1.11 because of Go modules) -$(warning Some recipes may not work as expected as the current Go runtime is '$(GO_VERSION_NUMBER)') - endif - else - # This repository isn't using Go modules (yet). - GOVENDOR := $(FIRST_GOPATH)/bin/govendor - endif -endif PROMU := $(FIRST_GOPATH)/bin/promu pkgs = ./... @@ -78,17 +55,23 @@ ifneq ($(shell which gotestsum),) endif endif -PROMU_VERSION ?= 0.12.0 +PROMU_VERSION ?= 0.13.0 PROMU_URL := https://github.com/prometheus/promu/releases/download/v$(PROMU_VERSION)/promu-$(PROMU_VERSION).$(GO_BUILD_PLATFORM).tar.gz GOLANGCI_LINT := GOLANGCI_LINT_OPTS ?= -GOLANGCI_LINT_VERSION ?= v1.39.0 +GOLANGCI_LINT_VERSION ?= v1.45.2 # golangci-lint only supports linux, darwin and windows platforms on i386/amd64. # windows isn't included here because of the path separator being different. ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin)) ifeq ($(GOHOSTARCH),$(filter $(GOHOSTARCH),amd64 i386)) - GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + # If we're in CI and there is an Actions file, that means the linter + # is being run in Actions, so we don't need to run it here. + ifeq (,$(CIRCLE_JOB)) + GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + else ifeq (,$(wildcard .github/workflows/golangci-lint.yml)) + GOLANGCI_LINT := $(FIRST_GOPATH)/bin/golangci-lint + endif endif endif @@ -144,32 +127,25 @@ common-check_license: .PHONY: common-deps common-deps: @echo ">> getting dependencies" -ifdef GO111MODULE - GO111MODULE=$(GO111MODULE) $(GO) mod download -else - $(GO) get $(GOOPTS) -t ./... -endif + $(GO) mod download .PHONY: update-go-deps update-go-deps: @echo ">> updating Go dependencies" @for m in $$($(GO) list -mod=readonly -m -f '{{ if and (not .Indirect) (not .Main)}}{{.Path}}{{end}}' all); do \ - $(GO) get $$m; \ + $(GO) get -d $$m; \ done - GO111MODULE=$(GO111MODULE) $(GO) mod tidy -ifneq (,$(wildcard vendor)) - GO111MODULE=$(GO111MODULE) $(GO) mod vendor -endif + $(GO) mod tidy .PHONY: common-test-short common-test-short: $(GOTEST_DIR) @echo ">> running short tests" - GO111MODULE=$(GO111MODULE) $(GOTEST) -short $(GOOPTS) $(pkgs) + $(GOTEST) -short $(GOOPTS) $(pkgs) .PHONY: common-test common-test: $(GOTEST_DIR) @echo ">> running all tests" - GO111MODULE=$(GO111MODULE) $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) + $(GOTEST) $(test-flags) $(GOOPTS) $(pkgs) $(GOTEST_DIR): @mkdir -p $@ @@ -177,25 +153,21 @@ $(GOTEST_DIR): .PHONY: common-format common-format: @echo ">> formatting code" - GO111MODULE=$(GO111MODULE) $(GO) fmt $(pkgs) + $(GO) fmt $(pkgs) .PHONY: common-vet common-vet: @echo ">> vetting code" - GO111MODULE=$(GO111MODULE) $(GO) vet $(GOOPTS) $(pkgs) + $(GO) vet $(GOOPTS) $(pkgs) .PHONY: common-lint common-lint: $(GOLANGCI_LINT) ifdef GOLANGCI_LINT @echo ">> running golangci-lint" -ifdef GO111MODULE # 'go list' needs to be executed before staticcheck to prepopulate the modules cache. # Otherwise staticcheck might fail randomly for some reason not yet explained. - GO111MODULE=$(GO111MODULE) $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null - GO111MODULE=$(GO111MODULE) $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) -else - $(GOLANGCI_LINT) run $(pkgs) -endif + $(GO) list -e -compiled -test=true -export=false -deps=true -find=false -tags= -- ./... > /dev/null + $(GOLANGCI_LINT) run $(GOLANGCI_LINT_OPTS) $(pkgs) endif .PHONY: common-yamllint @@ -212,28 +184,15 @@ endif common-staticcheck: lint .PHONY: common-unused -common-unused: $(GOVENDOR) -ifdef GOVENDOR - @echo ">> running check for unused packages" - @$(GOVENDOR) list +unused | grep . && exit 1 || echo 'No unused packages' -else -ifdef GO111MODULE +common-unused: @echo ">> running check for unused/missing packages in go.mod" - GO111MODULE=$(GO111MODULE) $(GO) mod tidy -ifeq (,$(wildcard vendor)) + $(GO) mod tidy @git diff --exit-code -- go.sum go.mod -else - @echo ">> running check for unused packages in vendor/" - GO111MODULE=$(GO111MODULE) $(GO) mod vendor - @git diff --exit-code -- go.sum go.mod vendor/ -endif -endif -endif .PHONY: common-build common-build: promu @echo ">> building binaries" - GO111MODULE=$(GO111MODULE) $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) + $(PROMU) build --prefix $(PREFIX) $(PROMU_BINARIES) .PHONY: common-tarball common-tarball: promu @@ -289,12 +248,6 @@ $(GOLANGCI_LINT): | sh -s -- -b $(FIRST_GOPATH)/bin $(GOLANGCI_LINT_VERSION) endif -ifdef GOVENDOR -.PHONY: $(GOVENDOR) -$(GOVENDOR): - GOOS= GOARCH= $(GO) get -u github.com/kardianos/govendor -endif - .PHONY: precheck precheck:: diff --git a/vendor/github.com/prometheus/procfs/SECURITY.md b/vendor/github.com/prometheus/procfs/SECURITY.md index 67741f015..fed02d85c 100644 --- a/vendor/github.com/prometheus/procfs/SECURITY.md +++ b/vendor/github.com/prometheus/procfs/SECURITY.md @@ -3,4 +3,4 @@ The Prometheus security policy, including how to report vulnerabilities, can be found here: -https://prometheus.io/docs/operating/security/ + diff --git a/vendor/github.com/prometheus/procfs/arp.go b/vendor/github.com/prometheus/procfs/arp.go index 4e47e6172..68f36e888 100644 --- a/vendor/github.com/prometheus/procfs/arp.go +++ b/vendor/github.com/prometheus/procfs/arp.go @@ -15,11 +15,28 @@ package procfs import ( "fmt" - "io/ioutil" "net" + "os" + "strconv" "strings" ) +// Learned from include/uapi/linux/if_arp.h. +const ( + // completed entry (ha valid). + ATFComplete = 0x02 + // permanent entry. + ATFPermanent = 0x04 + // Publish entry. + ATFPublish = 0x08 + // Has requested trailers. + ATFUseTrailers = 0x10 + // Obsoleted: Want to use a netmask (only for proxy entries). + ATFNetmask = 0x20 + // Don't answer this addresses. + ATFDontPublish = 0x40 +) + // ARPEntry contains a single row of the columnar data represented in // /proc/net/arp. type ARPEntry struct { @@ -29,12 +46,14 @@ type ARPEntry struct { HWAddr net.HardwareAddr // Name of the device Device string + // Flags + Flags byte } // GatherARPEntries retrieves all the ARP entries, parse the relevant columns, // and then return a slice of ARPEntry's. func (fs FS) GatherARPEntries() ([]ARPEntry, error) { - data, err := ioutil.ReadFile(fs.proc.Path("net/arp")) + data, err := os.ReadFile(fs.proc.Path("net/arp")) if err != nil { return nil, fmt.Errorf("error reading arp %q: %w", fs.proc.Path("net/arp"), err) } @@ -72,14 +91,26 @@ func parseARPEntries(data []byte) ([]ARPEntry, error) { } func parseARPEntry(columns []string) (ARPEntry, error) { + entry := ARPEntry{Device: columns[5]} ip := net.ParseIP(columns[0]) - mac := net.HardwareAddr(columns[3]) + entry.IPAddr = ip - entry := ARPEntry{ - IPAddr: ip, - HWAddr: mac, - Device: columns[5], + if mac, err := net.ParseMAC(columns[3]); err == nil { + entry.HWAddr = mac + } else { + return ARPEntry{}, err + } + + if flags, err := strconv.ParseUint(columns[2], 0, 8); err == nil { + entry.Flags = byte(flags) + } else { + return ARPEntry{}, err } return entry, nil } + +// IsComplete returns true if ARP entry is marked with complete flag. +func (entry *ARPEntry) IsComplete() bool { + return entry.Flags&ATFComplete != 0 +} diff --git a/vendor/github.com/prometheus/procfs/cpuinfo.go b/vendor/github.com/prometheus/procfs/cpuinfo.go index 5623b24a1..ff6b927da 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux // +build linux package procfs @@ -27,7 +28,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// CPUInfo contains general information about a system CPU found in /proc/cpuinfo +// CPUInfo contains general information about a system CPU found in /proc/cpuinfo. type CPUInfo struct { Processor uint VendorID string @@ -469,7 +470,7 @@ func parseCPUInfoDummy(_ []byte) ([]CPUInfo, error) { // nolint:unused,deadcode } // firstNonEmptyLine advances the scanner to the first non-empty line -// and returns the contents of that line +// and returns the contents of that line. func firstNonEmptyLine(scanner *bufio.Scanner) string { for scanner.Scan() { line := scanner.Text() diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go index 44b590ed3..64cfd534c 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_armx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_armx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (arm || arm64) // +build linux // +build arm arm64 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go index 91e272573..c11207f3a 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_mipsx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (mips || mipsle || mips64 || mips64le) // +build linux // +build mips mipsle mips64 mips64le diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_others.go b/vendor/github.com/prometheus/procfs/cpuinfo_others.go index 95b5b4ec4..ea41bf2ca 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_others.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_others.go @@ -11,8 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux -// +build !386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x +//go:build linux && !386 && !amd64 && !arm && !arm64 && !mips && !mips64 && !mips64le && !mipsle && !ppc64 && !ppc64le && !riscv64 && !s390x +// +build linux,!386,!amd64,!arm,!arm64,!mips,!mips64,!mips64le,!mipsle,!ppc64,!ppc64le,!riscv64,!s390x package procfs diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go index 6068bd571..003bc2ad4 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_ppcx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (ppc64 || ppc64le) // +build linux // +build ppc64 ppc64le diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go index e83c2e207..1c9b7313b 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_riscvx.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (riscv || riscv64) // +build linux // +build riscv riscv64 diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go index 26814eeba..fa3686bc0 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_s390x.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux // +build linux package procfs diff --git a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go index d5bedf97f..a0ef55562 100644 --- a/vendor/github.com/prometheus/procfs/cpuinfo_x86.go +++ b/vendor/github.com/prometheus/procfs/cpuinfo_x86.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build linux && (386 || amd64) // +build linux // +build 386 amd64 diff --git a/vendor/github.com/prometheus/procfs/fixtures.ttar b/vendor/github.com/prometheus/procfs/fixtures.ttar deleted file mode 100644 index 5e7eeef4a..000000000 --- a/vendor/github.com/prometheus/procfs/fixtures.ttar +++ /dev/null @@ -1,7673 +0,0 @@ -# Archive created by ttar -c -f fixtures.ttar fixtures/ -Directory: fixtures -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/cmdline -Lines: 1 -vimNULLBYTEtest.goNULLBYTE+10NULLBYTEEOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/comm -Lines: 1 -vim -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/cwd -SymlinkTo: /usr/bin -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/environ -Lines: 1 -PATH=/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binNULLBYTEHOSTNAME=cd24e11f73a5NULLBYTETERM=xtermNULLBYTEGOLANG_VERSION=1.12.5NULLBYTEGOPATH=/goNULLBYTEHOME=/rootNULLBYTEEOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/exe -SymlinkTo: /usr/bin/vim -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/fd -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/0 -SymlinkTo: ../../symlinktargets/abc -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/1 -SymlinkTo: ../../symlinktargets/def -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/10 -SymlinkTo: ../../symlinktargets/xyz -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/2 -SymlinkTo: ../../symlinktargets/ghi -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fd/3 -SymlinkTo: ../../symlinktargets/uvw -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/fdinfo -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/0 -Lines: 6 -pos: 0 -flags: 02004000 -mnt_id: 13 -inotify wd:3 ino:1 sdev:34 mask:fce ignored_mask:0 fhandle-bytes:c fhandle-type:81 f_handle:000000000100000000000000 -inotify wd:2 ino:1300016 sdev:fd00002 mask:fce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:16003001ed3f022a -inotify wd:1 ino:2e0001 sdev:fd00000 mask:fce ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01002e00138e7c65 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/1 -Lines: 4 -pos: 0 -flags: 02004002 -mnt_id: 13 -eventfd-count: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/10 -Lines: 3 -pos: 0 -flags: 02004002 -mnt_id: 9 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/2 -Lines: 3 -pos: 0 -flags: 02004002 -mnt_id: 9 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/fdinfo/3 -Lines: 3 -pos: 0 -flags: 02004002 -mnt_id: 9 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/io -Lines: 7 -rchar: 750339 -wchar: 818609 -syscr: 7405 -syscw: 5245 -read_bytes: 1024 -write_bytes: 2048 -cancelled_write_bytes: -1024 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/limits -Lines: 17 -Limit Soft Limit Hard Limit Units -Max cpu time unlimited unlimited seconds -Max file size unlimited unlimited bytes -Max data size unlimited unlimited bytes -Max stack size 8388608 unlimited bytes -Max core file size 0 unlimited bytes -Max resident set unlimited unlimited bytes -Max processes 62898 62898 processes -Max open files 2048 4096 files -Max locked memory 18446744073708503040 18446744073708503040 bytes -Max address space 8589934592 unlimited bytes -Max file locks unlimited unlimited locks -Max pending signals 62898 62898 signals -Max msgqueue size 819200 819200 bytes -Max nice priority 0 0 -Max realtime priority 0 0 -Max realtime timeout unlimited unlimited us -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/mountstats -Lines: 20 -device rootfs mounted on / with fstype rootfs -device sysfs mounted on /sys with fstype sysfs -device proc mounted on /proc with fstype proc -device /dev/sda1 mounted on / with fstype ext4 -device 192.168.1.1:/srv/test mounted on /mnt/nfs/test with fstype nfs4 statvers=1.1 - opts: rw,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,acregmin=3,acregmax=60,acdirmin=30,acdirmax=60,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,mountaddr=192.168.1.1,clientaddr=192.168.1.5,local_lock=none - age: 13968 - caps: caps=0xfff7,wtmult=512,dtsize=32768,bsize=0,namlen=255 - nfsv4: bm0=0xfdffafff,bm1=0xf9be3e,bm2=0x0,acl=0x0,pnfs=not configured - sec: flavor=1,pseudoflavor=1 - events: 52 226 0 0 1 13 398 0 0 331 0 47 0 0 77 0 0 77 0 0 0 0 0 0 0 0 0 - bytes: 1207640230 0 0 0 1210214218 0 295483 0 - RPC iostats version: 1.0 p/v: 100003/4 (nfs) - xprt: tcp 832 0 1 0 11 6428 6428 0 12154 0 24 26 5726 - per-op statistics - NULL: 0 0 0 0 0 0 0 0 - READ: 1298 1298 0 207680 1210292152 6 79386 79407 - WRITE: 0 0 0 0 0 0 0 0 - ACCESS: 2927395007 2927394995 0 526931094212 362996810236 18446743919241604546 1667369447 1953587717 - -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/net -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/net/dev -Lines: 4 -Inter-| Receive | Transmit - face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed - lo: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - eth0: 438 5 0 0 0 0 0 0 648 8 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26231/ns -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/ns/mnt -SymlinkTo: mnt:[4026531840] -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/ns/net -SymlinkTo: net:[4026531993] -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/root -SymlinkTo: / -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/schedstat -Lines: 1 -411605849 93680043 79 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/smaps -Lines: 252 -00400000-00cb1000 r-xp 00000000 fd:01 952273 /bin/alertmanager -Size: 8900 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 2952 kB -Pss: 2952 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 2952 kB -Private_Dirty: 0 kB -Referenced: 2864 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd ex mr mw me dw sd -00cb1000-016b0000 r--p 008b1000 fd:01 952273 /bin/alertmanager -Size: 10236 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 6152 kB -Pss: 6152 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 6152 kB -Private_Dirty: 0 kB -Referenced: 5308 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd mr mw me dw sd -016b0000-0171a000 rw-p 012b0000 fd:01 952273 /bin/alertmanager -Size: 424 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 176 kB -Pss: 176 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 84 kB -Private_Dirty: 92 kB -Referenced: 176 kB -Anonymous: 92 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 12 kB -SwapPss: 12 kB -Locked: 0 kB -VmFlags: rd wr mr mw me dw ac sd -0171a000-0173f000 rw-p 00000000 00:00 0 -Size: 148 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 76 kB -Pss: 76 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 76 kB -Referenced: 76 kB -Anonymous: 76 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -c000000000-c000400000 rw-p 00000000 00:00 0 -Size: 4096 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 2564 kB -Pss: 2564 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 20 kB -Private_Dirty: 2544 kB -Referenced: 2544 kB -Anonymous: 2564 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 1100 kB -SwapPss: 1100 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -c000400000-c001600000 rw-p 00000000 00:00 0 -Size: 18432 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 16024 kB -Pss: 16024 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 5864 kB -Private_Dirty: 10160 kB -Referenced: 11944 kB -Anonymous: 16024 kB -LazyFree: 5848 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 440 kB -SwapPss: 440 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd nh -c001600000-c004000000 rw-p 00000000 00:00 0 -Size: 43008 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 0 kB -Pss: 0 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 0 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -7f0ab95ca000-7f0abbb7b000 rw-p 00000000 00:00 0 -Size: 38596 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 1992 kB -Pss: 1992 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 476 kB -Private_Dirty: 1516 kB -Referenced: 1828 kB -Anonymous: 1992 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 384 kB -SwapPss: 384 kB -Locked: 0 kB -VmFlags: rd wr mr mw me ac sd -7ffc07ecf000-7ffc07ef0000 rw-p 00000000 00:00 0 [stack] -Size: 132 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 8 kB -Pss: 8 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 8 kB -Referenced: 8 kB -Anonymous: 8 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 4 kB -SwapPss: 4 kB -Locked: 0 kB -VmFlags: rd wr mr mw me gd ac -7ffc07f9e000-7ffc07fa1000 r--p 00000000 00:00 0 [vvar] -Size: 12 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 0 kB -Pss: 0 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 0 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd mr pf io de dd sd -7ffc07fa1000-7ffc07fa3000 r-xp 00000000 00:00 0 [vdso] -Size: 8 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 4 kB -Pss: 0 kB -Shared_Clean: 4 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 4 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd ex mr mw me de sd -ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] -Size: 4 kB -KernelPageSize: 4 kB -MMUPageSize: 4 kB -Rss: 0 kB -Pss: 0 kB -Shared_Clean: 0 kB -Shared_Dirty: 0 kB -Private_Clean: 0 kB -Private_Dirty: 0 kB -Referenced: 0 kB -Anonymous: 0 kB -LazyFree: 0 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 0 kB -SwapPss: 0 kB -Locked: 0 kB -VmFlags: rd ex -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/smaps_rollup -Lines: 17 -00400000-ffffffffff601000 ---p 00000000 00:00 0 [rollup] -Rss: 29948 kB -Pss: 29944 kB -Shared_Clean: 4 kB -Shared_Dirty: 0 kB -Private_Clean: 15548 kB -Private_Dirty: 14396 kB -Referenced: 24752 kB -Anonymous: 20756 kB -LazyFree: 5848 kB -AnonHugePages: 0 kB -ShmemPmdMapped: 0 kB -Shared_Hugetlb: 0 kB -Private_Hugetlb: 0 kB -Swap: 1940 kB -SwapPss: 1940 kB -Locked: 0 kB -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/stat -Lines: 1 -26231 (vim) R 5392 7446 5392 34835 7446 4218880 32533 309516 26 82 1677 44 158 99 20 0 1 0 82375 56274944 1981 18446744073709551615 4194304 6294284 140736914091744 140736914087944 139965136429984 0 0 12288 1870679807 0 0 0 17 0 0 0 31 0 0 8391624 8481048 16420864 140736914093252 140736914093279 140736914093279 140736914096107 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/status -Lines: 53 - -Name: prometheus -Umask: 0022 -State: S (sleeping) -Tgid: 26231 -Ngid: 0 -Pid: 26231 -PPid: 1 -TracerPid: 0 -Uid: 1000 1000 1000 0 -Gid: 1001 1001 1001 0 -FDSize: 128 -Groups: -NStgid: 1 -NSpid: 1 -NSpgid: 1 -NSsid: 1 -VmPeak: 58472 kB -VmSize: 58440 kB -VmLck: 0 kB -VmPin: 0 kB -VmHWM: 8028 kB -VmRSS: 6716 kB -RssAnon: 2092 kB -RssFile: 4624 kB -RssShmem: 0 kB -VmData: 2580 kB -VmStk: 136 kB -VmExe: 948 kB -VmLib: 6816 kB -VmPTE: 128 kB -VmPMD: 12 kB -VmSwap: 660 kB -HugetlbPages: 0 kB -Threads: 1 -SigQ: 8/63965 -SigPnd: 0000000000000000 -ShdPnd: 0000000000000000 -SigBlk: 7be3c0fe28014a03 -SigIgn: 0000000000001000 -SigCgt: 00000001800004ec -CapInh: 0000000000000000 -CapPrm: 0000003fffffffff -CapEff: 0000003fffffffff -CapBnd: 0000003fffffffff -CapAmb: 0000000000000000 -Seccomp: 0 -Cpus_allowed: ff -Cpus_allowed_list: 0-7 -Mems_allowed: 00000000,00000001 -Mems_allowed_list: 0 -voluntary_ctxt_switches: 4742839 -nonvoluntary_ctxt_switches: 1727500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26231/wchan -Lines: 1 -poll_schedule_timeoutEOF -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26232 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/cmdline -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/comm -Lines: 1 -ata_sff -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/cwd -SymlinkTo: /does/not/exist -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26232/fd -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/0 -SymlinkTo: ../../symlinktargets/abc -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/1 -SymlinkTo: ../../symlinktargets/def -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/2 -SymlinkTo: ../../symlinktargets/ghi -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/3 -SymlinkTo: ../../symlinktargets/uvw -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/fd/4 -SymlinkTo: ../../symlinktargets/xyz -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/limits -Lines: 17 -Limit Soft Limit Hard Limit Units -Max cpu time unlimited unlimited seconds -Max file size unlimited unlimited bytes -Max data size unlimited unlimited bytes -Max stack size 8388608 unlimited bytes -Max core file size 0 unlimited bytes -Max resident set unlimited unlimited bytes -Max processes 29436 29436 processes -Max open files 1024 4096 files -Max locked memory 65536 65536 bytes -Max address space unlimited unlimited bytes -Max file locks unlimited unlimited locks -Max pending signals 29436 29436 signals -Max msgqueue size 819200 819200 bytes -Max nice priority 0 0 -Max realtime priority 0 0 -Max realtime timeout unlimited unlimited us -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/maps -Lines: 9 -55680ae1e000-55680ae20000 r--p 00000000 fd:01 47316994 /bin/cat -55680ae29000-55680ae2a000 rwxs 0000a000 fd:01 47316994 /bin/cat -55680bed6000-55680bef7000 rw-p 00000000 00:00 0 [heap] -7fdf964fc000-7fdf973f2000 r--p 00000000 fd:01 17432624 /usr/lib/locale/locale-archive -7fdf973f2000-7fdf97417000 r--p 00000000 fd:01 60571062 /lib/x86_64-linux-gnu/libc-2.29.so -7ffe9215c000-7ffe9217f000 rw-p 00000000 00:00 0 [stack] -7ffe921da000-7ffe921dd000 r--p 00000000 00:00 0 [vvar] -7ffe921dd000-7ffe921de000 r-xp 00000000 00:00 0 [vdso] -ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall] -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/root -SymlinkTo: /does/not/exist -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/stat -Lines: 1 -33 (ata_sff) S 2 0 0 0 -1 69238880 0 0 0 0 0 0 0 0 0 -20 1 0 5 0 0 18446744073709551615 0 0 0 0 0 0 0 2147483647 0 18446744073709551615 0 0 17 1 0 0 0 0 0 0 0 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26232/wchan -Lines: 1 -0EOF -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26233 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26233/cmdline -Lines: 1 -com.github.uiautomatorNULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTENULLBYTEEOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26233/schedstat -Lines: 8 - ____________________________________ -< this is a malformed schedstat file > - ------------------------------------ - \ ^__^ - \ (oo)\_______ - (__)\ )\/\ - ||----w | - || || -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/26234 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/26234/maps -Lines: 4 -08048000-08089000 r-xp 00000000 03:01 104219 /bin/tcsh -08089000-0808c000 rw-p 00041000 03:01 104219 /bin/tcsh -0808c000-08146000 rwxp 00000000 00:00 0 -40000000-40015000 r-xp 00000000 03:01 61874 /lib/ld-2.3.2.so -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/584 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/584/stat -Lines: 2 -1020 ((a b ) ( c d) ) R 28378 1020 28378 34842 1020 4218880 286 0 0 0 0 0 0 0 20 0 1 0 10839175 10395648 155 18446744073709551615 4194304 4238788 140736466511168 140736466511168 140609271124624 0 0 0 0 0 0 0 17 5 0 0 0 0 0 6336016 6337300 25579520 140736466515030 140736466515061 140736466515061 140736466518002 0 -#!/bin/cat /proc/self/stat -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/buddyinfo -Lines: 3 -Node 0, zone DMA 1 0 1 0 2 1 1 0 1 1 3 -Node 0, zone DMA32 759 572 791 475 194 45 12 0 0 0 0 -Node 0, zone Normal 4381 1093 185 1530 567 102 4 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/cmdline -Lines: 1 -BOOT_IMAGE=/vmlinuz-5.11.0-22-generic root=UUID=456a0345-450d-4f7b-b7c9-43e3241d99ad ro quiet splash vt.handoff=7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/cpuinfo -Lines: 216 -processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 799.998 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 0 -cpu cores : 4 -apicid : 0 -initial apicid : 0 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 1 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.037 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 1 -cpu cores : 4 -apicid : 2 -initial apicid : 2 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 2 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.010 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 2 -cpu cores : 4 -apicid : 4 -initial apicid : 4 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 3 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.028 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 3 -cpu cores : 4 -apicid : 6 -initial apicid : 6 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 4 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 799.989 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 0 -cpu cores : 4 -apicid : 1 -initial apicid : 1 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 5 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.083 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 1 -cpu cores : 4 -apicid : 3 -initial apicid : 3 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 6 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.017 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 2 -cpu cores : 4 -apicid : 5 -initial apicid : 5 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -processor : 7 -vendor_id : GenuineIntel -cpu family : 6 -model : 142 -model name : Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz -stepping : 10 -microcode : 0xb4 -cpu MHz : 800.030 -cache size : 8192 KB -physical id : 0 -siblings : 8 -core id : 3 -cpu cores : 4 -apicid : 7 -initial apicid : 7 -fpu : yes -fpu_exception : yes -cpuid level : 22 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp md_clear flush_l1d -bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs -bogomips : 4224.00 -clflush size : 64 -cache_alignment : 64 -address sizes : 39 bits physical, 48 bits virtual -power management: - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/crypto -Lines: 972 -name : ccm(aes) -driver : ccm_base(ctr(aes-aesni),cbcmac(aes-aesni)) -module : ccm -priority : 300 -refcnt : 4 -selftest : passed -internal : no -type : aead -async : no -blocksize : 1 -ivsize : 16 -maxauthsize : 16 -geniv : - -name : cbcmac(aes) -driver : cbcmac(aes-aesni) -module : ccm -priority : 300 -refcnt : 7 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 16 - -name : ecdh -driver : ecdh-generic -module : ecdh_generic -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : kpp -async : yes - -name : ecb(arc4) -driver : ecb(arc4)-generic -module : arc4 -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 1 -min keysize : 1 -max keysize : 256 -ivsize : 0 -chunksize : 1 -walksize : 1 - -name : arc4 -driver : arc4-generic -module : arc4 -priority : 0 -refcnt : 3 -selftest : passed -internal : no -type : cipher -blocksize : 1 -min keysize : 1 -max keysize : 256 - -name : crct10dif -driver : crct10dif-pclmul -module : crct10dif_pclmul -priority : 200 -refcnt : 2 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 2 - -name : crc32 -driver : crc32-pclmul -module : crc32_pclmul -priority : 200 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 4 - -name : __ghash -driver : cryptd(__ghash-pclmulqdqni) -module : kernel -priority : 50 -refcnt : 1 -selftest : passed -internal : yes -type : ahash -async : yes -blocksize : 16 -digestsize : 16 - -name : ghash -driver : ghash-clmulni -module : ghash_clmulni_intel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : ahash -async : yes -blocksize : 16 -digestsize : 16 - -name : __ghash -driver : __ghash-pclmulqdqni -module : ghash_clmulni_intel -priority : 0 -refcnt : 1 -selftest : passed -internal : yes -type : shash -blocksize : 16 -digestsize : 16 - -name : crc32c -driver : crc32c-intel -module : crc32c_intel -priority : 200 -refcnt : 5 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 4 - -name : cbc(aes) -driver : cbc(aes-aesni) -module : kernel -priority : 300 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : ctr(aes) -driver : ctr(aes-aesni) -module : kernel -priority : 300 -refcnt : 5 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 1 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : pkcs1pad(rsa,sha256) -driver : pkcs1pad(rsa-generic,sha256) -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : akcipher - -name : __xts(aes) -driver : cryptd(__xts-aes-aesni) -module : kernel -priority : 451 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 16 -min keysize : 32 -max keysize : 64 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : xts(aes) -driver : xts-aes-aesni -module : kernel -priority : 401 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 16 -min keysize : 32 -max keysize : 64 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ctr(aes) -driver : cryptd(__ctr-aes-aesni) -module : kernel -priority : 450 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 1 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : ctr(aes) -driver : ctr-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 1 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __cbc(aes) -driver : cryptd(__cbc-aes-aesni) -module : kernel -priority : 450 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : cbc(aes) -driver : cbc-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ecb(aes) -driver : cryptd(__ecb-aes-aesni) -module : kernel -priority : 450 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 0 -chunksize : 16 -walksize : 16 - -name : ecb(aes) -driver : ecb-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : yes -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 0 -chunksize : 16 -walksize : 16 - -name : __generic-gcm-aes-aesni -driver : cryptd(__driver-generic-gcm-aes-aesni) -module : kernel -priority : 50 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : yes -blocksize : 1 -ivsize : 12 -maxauthsize : 16 -geniv : - -name : gcm(aes) -driver : generic-gcm-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : aead -async : yes -blocksize : 1 -ivsize : 12 -maxauthsize : 16 -geniv : - -name : __generic-gcm-aes-aesni -driver : __driver-generic-gcm-aes-aesni -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : no -blocksize : 1 -ivsize : 12 -maxauthsize : 16 -geniv : - -name : __gcm-aes-aesni -driver : cryptd(__driver-gcm-aes-aesni) -module : kernel -priority : 50 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : yes -blocksize : 1 -ivsize : 8 -maxauthsize : 16 -geniv : - -name : rfc4106(gcm(aes)) -driver : rfc4106-gcm-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : no -type : aead -async : yes -blocksize : 1 -ivsize : 8 -maxauthsize : 16 -geniv : - -name : __gcm-aes-aesni -driver : __driver-gcm-aes-aesni -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : yes -type : aead -async : no -blocksize : 1 -ivsize : 8 -maxauthsize : 16 -geniv : - -name : __xts(aes) -driver : __xts-aes-aesni -module : kernel -priority : 401 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 16 -min keysize : 32 -max keysize : 64 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ctr(aes) -driver : __ctr-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 1 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __cbc(aes) -driver : __cbc-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 16 -chunksize : 16 -walksize : 16 - -name : __ecb(aes) -driver : __ecb-aes-aesni -module : kernel -priority : 400 -refcnt : 1 -selftest : passed -internal : yes -type : skcipher -async : no -blocksize : 16 -min keysize : 16 -max keysize : 32 -ivsize : 0 -chunksize : 16 -walksize : 16 - -name : __aes -driver : __aes-aesni -module : kernel -priority : 300 -refcnt : 1 -selftest : passed -internal : yes -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -name : aes -driver : aes-aesni -module : kernel -priority : 300 -refcnt : 8 -selftest : passed -internal : no -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -name : hmac(sha1) -driver : hmac(sha1-generic) -module : kernel -priority : 100 -refcnt : 9 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 20 - -name : ghash -driver : ghash-generic -module : kernel -priority : 100 -refcnt : 3 -selftest : passed -internal : no -type : shash -blocksize : 16 -digestsize : 16 - -name : jitterentropy_rng -driver : jitterentropy_rng -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha256 -module : kernel -priority : 221 -refcnt : 2 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha512 -module : kernel -priority : 220 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha384 -module : kernel -priority : 219 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_hmac_sha1 -module : kernel -priority : 218 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha256 -module : kernel -priority : 217 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha512 -module : kernel -priority : 216 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha384 -module : kernel -priority : 215 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_sha1 -module : kernel -priority : 214 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_ctr_aes256 -module : kernel -priority : 213 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_ctr_aes192 -module : kernel -priority : 212 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_nopr_ctr_aes128 -module : kernel -priority : 211 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : hmac(sha256) -driver : hmac(sha256-generic) -module : kernel -priority : 100 -refcnt : 10 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 32 - -name : stdrng -driver : drbg_pr_hmac_sha256 -module : kernel -priority : 210 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_hmac_sha512 -module : kernel -priority : 209 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_hmac_sha384 -module : kernel -priority : 208 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_hmac_sha1 -module : kernel -priority : 207 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha256 -module : kernel -priority : 206 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha512 -module : kernel -priority : 205 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha384 -module : kernel -priority : 204 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_sha1 -module : kernel -priority : 203 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_ctr_aes256 -module : kernel -priority : 202 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_ctr_aes192 -module : kernel -priority : 201 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : stdrng -driver : drbg_pr_ctr_aes128 -module : kernel -priority : 200 -refcnt : 1 -selftest : passed -internal : no -type : rng -seedsize : 0 - -name : 842 -driver : 842-scomp -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : 842 -driver : 842-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : lzo-rle -driver : lzo-rle-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : lzo-rle -driver : lzo-rle-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : lzo -driver : lzo-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : lzo -driver : lzo-generic -module : kernel -priority : 0 -refcnt : 9 -selftest : passed -internal : no -type : compression - -name : crct10dif -driver : crct10dif-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 2 - -name : crc32c -driver : crc32c-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 4 - -name : zlib-deflate -driver : zlib-deflate-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : deflate -driver : deflate-scomp -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : scomp - -name : deflate -driver : deflate-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : aes -driver : aes-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -name : sha224 -driver : sha224-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 28 - -name : sha256 -driver : sha256-generic -module : kernel -priority : 100 -refcnt : 11 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 32 - -name : sha1 -driver : sha1-generic -module : kernel -priority : 100 -refcnt : 11 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 20 - -name : md5 -driver : md5-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 64 -digestsize : 16 - -name : ecb(cipher_null) -driver : ecb-cipher_null -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : skcipher -async : no -blocksize : 1 -min keysize : 0 -max keysize : 0 -ivsize : 0 -chunksize : 1 -walksize : 1 - -name : digest_null -driver : digest_null-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : shash -blocksize : 1 -digestsize : 0 - -name : compress_null -driver : compress_null-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : compression - -name : cipher_null -driver : cipher_null-generic -module : kernel -priority : 0 -refcnt : 1 -selftest : passed -internal : no -type : cipher -blocksize : 1 -min keysize : 0 -max keysize : 0 - -name : rsa -driver : rsa-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : akcipher - -name : dh -driver : dh-generic -module : kernel -priority : 100 -refcnt : 1 -selftest : passed -internal : no -type : kpp - -name : aes -driver : aes-asm -module : kernel -priority : 200 -refcnt : 1 -selftest : passed -internal : no -type : cipher -blocksize : 16 -min keysize : 16 -max keysize : 32 - -Mode: 444 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/diskstats -Lines: 52 - 1 0 ram0 0 0 0 0 0 0 0 0 0 0 0 - 1 1 ram1 0 0 0 0 0 0 0 0 0 0 0 - 1 2 ram2 0 0 0 0 0 0 0 0 0 0 0 - 1 3 ram3 0 0 0 0 0 0 0 0 0 0 0 - 1 4 ram4 0 0 0 0 0 0 0 0 0 0 0 - 1 5 ram5 0 0 0 0 0 0 0 0 0 0 0 - 1 6 ram6 0 0 0 0 0 0 0 0 0 0 0 - 1 7 ram7 0 0 0 0 0 0 0 0 0 0 0 - 1 8 ram8 0 0 0 0 0 0 0 0 0 0 0 - 1 9 ram9 0 0 0 0 0 0 0 0 0 0 0 - 1 10 ram10 0 0 0 0 0 0 0 0 0 0 0 - 1 11 ram11 0 0 0 0 0 0 0 0 0 0 0 - 1 12 ram12 0 0 0 0 0 0 0 0 0 0 0 - 1 13 ram13 0 0 0 0 0 0 0 0 0 0 0 - 1 14 ram14 0 0 0 0 0 0 0 0 0 0 0 - 1 15 ram15 0 0 0 0 0 0 0 0 0 0 0 - 7 0 loop0 0 0 0 0 0 0 0 0 0 0 0 - 7 1 loop1 0 0 0 0 0 0 0 0 0 0 0 - 7 2 loop2 0 0 0 0 0 0 0 0 0 0 0 - 7 3 loop3 0 0 0 0 0 0 0 0 0 0 0 - 7 4 loop4 0 0 0 0 0 0 0 0 0 0 0 - 7 5 loop5 0 0 0 0 0 0 0 0 0 0 0 - 7 6 loop6 0 0 0 0 0 0 0 0 0 0 0 - 7 7 loop7 0 0 0 0 0 0 0 0 0 0 0 - 8 0 sda 25354637 34367663 1003346126 18492372 28444756 11134226 505697032 63877960 0 9653880 82621804 - 8 1 sda1 250 0 2000 36 0 0 0 0 0 36 36 - 8 2 sda2 246 0 1968 32 0 0 0 0 0 32 32 - 8 3 sda3 340 13 2818 52 11 8 152 8 0 56 60 - 8 4 sda4 25353629 34367650 1003337964 18492232 27448755 11134218 505696880 61593380 0 7576432 80332428 - 252 0 dm-0 59910002 0 1003337218 46229572 39231014 0 505696880 1158557800 0 11325968 1206301256 - 252 1 dm-1 388 0 3104 84 74 0 592 0 0 76 84 - 252 2 dm-2 11571 0 308350 6536 153522 0 5093416 122884 0 65400 129416 - 252 3 dm-3 3870 0 3870 104 0 0 0 0 0 16 104 - 252 4 dm-4 392 0 1034 28 38 0 137 16 0 24 44 - 252 5 dm-5 3729 0 84279 924 98918 0 1151688 104684 0 58848 105632 - 179 0 mmcblk0 192 3 1560 156 0 0 0 0 0 136 156 - 179 1 mmcblk0p1 17 3 160 24 0 0 0 0 0 24 24 - 179 2 mmcblk0p2 95 0 760 68 0 0 0 0 0 68 68 - 2 0 fd0 2 0 16 80 0 0 0 0 0 80 80 - 254 0 vda 1775784 15386 32670882 8655768 6038856 20711856 213637440 2069221364 0 41614592 2077872228 - 254 1 vda1 668 85 5984 956 207 4266 35784 32772 0 8808 33720 - 254 2 vda2 1774936 15266 32663262 8654692 5991028 20707590 213601656 2069152216 0 41607628 2077801992 - 11 0 sr0 0 0 0 0 0 0 0 0 0 0 0 - 259 0 nvme0n1 47114 4 4643973 21650 1078320 43950 39451633 1011053 0 222766 1032546 - 259 1 nvme0n1p1 1140 0 9370 16 1 0 1 0 0 16 16 - 259 2 nvme0n1p2 45914 4 4631243 21626 1036885 43950 39451632 919480 0 131580 940970 - 8 0 sdb 326552 841 9657779 84 41822 2895 1972905 5007 0 60730 67070 68851 0 1925173784 11130 - 8 1 sdb1 231 3 34466 4 24 23 106 0 0 64 64 0 0 0 0 - 8 2 sdb2 326310 838 9622281 67 40726 2872 1972799 4924 0 58250 64567 68851 0 1925173784 11130 - 8 0 sdc 14202 71 579164 21861 2995 1589 180500 40875 0 11628 55200 0 0 0 0 127 182 - 8 1 sdc1 1027 0 13795 5021 2 0 4096 3 0 690 4579 0 0 0 0 0 0 - 8 2 sdc2 13126 71 561749 16802 2830 1589 176404 40620 0 10931 50449 0 0 0 0 0 0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/fs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/fs/fscache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/fs/fscache/stats -Lines: 24 -FS-Cache statistics -Cookies: idx=3 dat=67877 spc=0 -Objects: alc=67473 nal=0 avl=67473 ded=388 -ChkAux : non=12 ok=33 upd=44 obs=55 -Pages : mrk=547164 unc=364577 -Acquire: n=67880 nul=98 noc=25 ok=67780 nbf=39 oom=26 -Lookups: n=67473 neg=67470 pos=58 crt=67473 tmo=85 -Invals : n=14 run=13 -Updates: n=7 nul=3 run=8 -Relinqs: n=394 nul=1 wcr=2 rtr=3 -AttrChg: n=6 ok=5 nbf=4 oom=3 run=2 -Allocs : n=20 ok=19 wt=18 nbf=17 int=16 -Allocs : ops=15 owt=14 abt=13 -Retrvls: n=151959 ok=82823 wt=23467 nod=69136 nbf=15 int=69 oom=43 -Retrvls: ops=151959 owt=42747 abt=44 -Stores : n=225565 ok=225565 agn=12 nbf=13 oom=14 -Stores : ops=69156 run=294721 pgs=225565 rxd=225565 olm=43 -VmScan : nos=364512 gon=2 bsy=43 can=12 wt=66 -Ops : pend=42753 run=221129 enq=628798 can=11 rej=88 -Ops : ini=377538 dfr=27 rel=377538 gc=37 -CacheOp: alo=1 luo=2 luc=3 gro=4 -CacheOp: inv=5 upo=6 dro=7 pto=8 atc=9 syn=10 -CacheOp: rap=11 ras=12 alp=13 als=14 wrp=15 ucp=16 dsp=17 -CacheEv: nsp=18 stl=19 rtr=20 cul=21EOF -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/fs/xfs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/fs/xfs/stat -Lines: 23 -extent_alloc 92447 97589 92448 93751 -abt 0 0 0 0 -blk_map 1767055 188820 184891 92447 92448 2140766 0 -bmbt 0 0 0 0 -dir 185039 92447 92444 136422 -trans 706 944304 0 -ig 185045 58807 0 126238 0 33637 22 -log 2883 113448 9 17360 739 -push_ail 945014 0 134260 15483 0 3940 464 159985 0 40 -xstrat 92447 0 -rw 107739 94045 -attr 4 0 0 0 -icluster 8677 7849 135802 -vnodes 92601 0 0 0 92444 92444 92444 0 -buf 2666287 7122 2659202 3599 2 7085 0 10297 7085 -abtb2 184941 1277345 13257 13278 0 0 0 0 0 0 0 0 0 0 2746147 -abtc2 345295 2416764 172637 172658 0 0 0 0 0 0 0 0 0 0 21406023 -bmbt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -ibt2 343004 1358467 0 0 0 0 0 0 0 0 0 0 0 0 0 -fibt2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -qm 0 0 0 0 0 0 0 0 -xpc 399724544 92823103 86219234 -debug 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/loadavg -Lines: 1 -0.02 0.04 0.05 1/497 11947 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/mdstat -Lines: 60 -Personalities : [linear] [multipath] [raid0] [raid1] [raid6] [raid5] [raid4] [raid10] - -md3 : active raid6 sda1[8] sdh1[7] sdg1[6] sdf1[5] sde1[11] sdd1[3] sdc1[10] sdb1[9] sdd1[10](S) sdd2[11](S) - 5853468288 blocks super 1.2 level 6, 64k chunk, algorithm 2 [8/8] [UUUUUUUU] - -md127 : active raid1 sdi2[0] sdj2[1] - 312319552 blocks [2/2] [UU] - -md0 : active raid1 sdi1[0] sdj1[1] - 248896 blocks [2/2] [UU] - -md4 : inactive raid1 sda3[0](F) sdb3[1](S) - 4883648 blocks [2/2] [UU] - -md6 : active raid1 sdb2[2](F) sdc[1](S) sda2[0] - 195310144 blocks [2/1] [U_] - [=>...................] recovery = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec - -md8 : active raid1 sdb1[1] sda1[0] sdc[2](S) sde[3](S) - 195310144 blocks [2/2] [UU] - [=>...................] resync = 8.5% (16775552/195310144) finish=17.0min speed=259783K/sec - -md201 : active raid1 sda3[0] sdb3[1] - 1993728 blocks super 1.2 [2/2] [UU] - [=>...................] check = 5.7% (114176/1993728) finish=0.2min speed=114176K/sec - -md7 : active raid6 sdb1[0] sde1[3] sdd1[2] sdc1[1](F) - 7813735424 blocks super 1.2 level 6, 512k chunk, algorithm 2 [4/3] [U_UU] - bitmap: 0/30 pages [0KB], 65536KB chunk - -md9 : active raid1 sdc2[2] sdd2[3] sdb2[1] sda2[0] sde[4](F) sdf[5](F) sdg[6](S) - 523968 blocks super 1.2 [4/4] [UUUU] - resync=DELAYED - -md10 : active raid0 sda1[0] sdb1[1] - 314159265 blocks 64k chunks - -md11 : active (auto-read-only) raid1 sdb2[0] sdc2[1] sdc3[2](F) hda[4](S) ssdc2[3](S) - 4190208 blocks super 1.2 [2/2] [UU] - resync=PENDING - -md12 : active raid0 sdc2[0] sdd2[1] - 3886394368 blocks super 1.2 512k chunks - -md126 : active raid0 sdb[1] sdc[0] - 1855870976 blocks super external:/md127/0 128k chunks - -md219 : inactive sdb[2](S) sdc[1](S) sda[0](S) - 7932 blocks super external:imsm - -md00 : active raid0 xvdb[0] - 4186624 blocks super 1.2 256k chunks - -md120 : active linear sda1[1] sdb1[0] - 2095104 blocks super 1.2 0k rounding - -md101 : active (read-only) raid0 sdb[2] sdd[1] sdc[0] - 322560 blocks super 1.2 512k chunks - -unused devices: -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/meminfo -Lines: 42 -MemTotal: 15666184 kB -MemFree: 440324 kB -Buffers: 1020128 kB -Cached: 12007640 kB -SwapCached: 0 kB -Active: 6761276 kB -Inactive: 6532708 kB -Active(anon): 267256 kB -Inactive(anon): 268 kB -Active(file): 6494020 kB -Inactive(file): 6532440 kB -Unevictable: 0 kB -Mlocked: 0 kB -SwapTotal: 0 kB -SwapFree: 0 kB -Dirty: 768 kB -Writeback: 0 kB -AnonPages: 266216 kB -Mapped: 44204 kB -Shmem: 1308 kB -Slab: 1807264 kB -SReclaimable: 1738124 kB -SUnreclaim: 69140 kB -KernelStack: 1616 kB -PageTables: 5288 kB -NFS_Unstable: 0 kB -Bounce: 0 kB -WritebackTmp: 0 kB -CommitLimit: 7833092 kB -Committed_AS: 530844 kB -VmallocTotal: 34359738367 kB -VmallocUsed: 36596 kB -VmallocChunk: 34359637840 kB -HardwareCorrupted: 0 kB -AnonHugePages: 12288 kB -HugePages_Total: 0 -HugePages_Free: 0 -HugePages_Rsvd: 0 -HugePages_Surp: 0 -Hugepagesize: 2048 kB -DirectMap4k: 91136 kB -DirectMap2M: 16039936 kB -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/net -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/arp -Lines: 2 -IP address HW type Flags HW address Mask Device -192.168.224.1 0x1 0x2 00:50:56:c0:00:08 * ens33 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/dev -Lines: 6 -Inter-| Receive | Transmit - face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed -vethf345468: 648 8 0 0 0 0 0 0 438 5 0 0 0 0 0 0 - lo: 1664039048 1566805 0 0 0 0 0 0 1664039048 1566805 0 0 0 0 0 0 -docker0: 2568 38 0 0 0 0 0 0 438 5 0 0 0 0 0 0 - eth0: 874354587 1036395 0 0 0 0 0 0 563352563 732147 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/ip_vs -Lines: 21 -IP Virtual Server version 1.2.1 (size=4096) -Prot LocalAddress:Port Scheduler Flags - -> RemoteAddress:Port Forward Weight ActiveConn InActConn -TCP C0A80016:0CEA wlc - -> C0A85216:0CEA Tunnel 100 248 2 - -> C0A85318:0CEA Tunnel 100 248 2 - -> C0A85315:0CEA Tunnel 100 248 1 -TCP C0A80039:0CEA wlc - -> C0A85416:0CEA Tunnel 0 0 0 - -> C0A85215:0CEA Tunnel 100 1499 0 - -> C0A83215:0CEA Tunnel 100 1498 0 -TCP C0A80037:0CEA wlc - -> C0A8321A:0CEA Tunnel 0 0 0 - -> C0A83120:0CEA Tunnel 100 0 0 -TCP [2620:0000:0000:0000:0000:0000:0000:0001]:0050 sh - -> [2620:0000:0000:0000:0000:0000:0000:0002]:0050 Route 1 0 0 - -> [2620:0000:0000:0000:0000:0000:0000:0003]:0050 Route 1 0 0 - -> [2620:0000:0000:0000:0000:0000:0000:0004]:0050 Route 1 1 1 -FWM 10001000 wlc - -> C0A8321A:0CEA Route 0 0 1 - -> C0A83215:0CEA Route 0 0 2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/ip_vs_stats -Lines: 6 - Total Incoming Outgoing Incoming Outgoing - Conns Packets Packets Bytes Bytes - 16AA370 E33656E5 0 51D8C8883AB3 0 - - Conns/s Pkts/s Pkts/s Bytes/s Bytes/s - 4 1FB3C 0 1282A8F 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/protocols -Lines: 14 -protocol size sockets memory press maxhdr slab module cl co di ac io in de sh ss gs se re sp bi br ha uh gp em -PACKET 1344 2 -1 NI 0 no kernel n n n n n n n n n n n n n n n n n n n -PINGv6 1112 0 -1 NI 0 yes kernel y y y n n y n n y y y y n y y y y y n -RAWv6 1112 1 -1 NI 0 yes kernel y y y n y y y n y y y y n y y y y n n -UDPLITEv6 1216 0 57 NI 0 yes kernel y y y n y y y n y y y y n n n y y y n -UDPv6 1216 10 57 NI 0 yes kernel y y y n y y y n y y y y n n n y y y n -TCPv6 2144 1937 1225378 no 320 yes kernel y y y y y y y y y y y y y n y y y y y -UNIX 1024 120 -1 NI 0 yes kernel n n n n n n n n n n n n n n n n n n n -UDP-Lite 1024 0 57 NI 0 yes kernel y y y n y y y n y y y y y n n y y y n -PING 904 0 -1 NI 0 yes kernel y y y n n y n n y y y y n y y y y y n -RAW 912 0 -1 NI 0 yes kernel y y y n y y y n y y y y n y y y y n n -UDP 1024 73 57 NI 0 yes kernel y y y n y y y n y y y y y n n y y y n -TCP 1984 93064 1225378 yes 320 yes kernel y y y y y y y y y y y y y n y y y y y -NETLINK 1040 16 -1 NI 0 no kernel n n n n n n n n n n n n n n n n n n n -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/net/rpc -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/rpc/nfs -Lines: 5 -net 18628 0 18628 6 -rpc 4329785 0 4338291 -proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2 -proc3 22 1 4084749 29200 94754 32580 186 47747 7981 8639 0 6356 0 6962 0 7958 0 0 241 4 4 2 39 -proc4 61 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/rpc/nfsd -Lines: 11 -rc 0 6 18622 -fh 0 0 0 0 0 -io 157286400 0 -th 8 0 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 -ra 32 0 0 0 0 0 0 0 0 0 0 0 -net 18628 0 18628 6 -rpc 18628 0 0 0 0 -proc2 18 2 69 0 0 4410 0 0 0 0 0 0 0 0 0 0 0 99 2 -proc3 22 2 112 0 2719 111 0 0 0 0 0 0 0 0 0 0 0 27 216 0 2 1 0 -proc4 2 2 10853 -proc4ops 72 0 0 0 1098 2 0 0 0 0 8179 5896 0 0 0 0 5900 0 0 2 0 2 0 9609 0 2 150 1272 0 0 0 1236 0 0 0 0 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/sockstat -Lines: 6 -sockets: used 1602 -TCP: inuse 35 orphan 0 tw 4 alloc 59 mem 22 -UDP: inuse 12 mem 62 -UDPLITE: inuse 0 -RAW: inuse 0 -FRAG: inuse 0 memory 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/sockstat6 -Lines: 5 -TCP6: inuse 17 -UDP6: inuse 9 -UDPLITE6: inuse 0 -RAW6: inuse 1 -FRAG6: inuse 0 memory 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/softnet_stat -Lines: 2 -00015c73 00020e76 F0000769 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 -01663fb2 00000000 000109a4 00000000 00000000 00000000 00000000 00000000 00000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/softnet_stat.broken -Lines: 1 -00015c73 00020e76 F0000769 00000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/net/stat -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/stat/arp_cache -Lines: 3 -entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards table_fulls -00000014 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008 00000009 0000000a 0000000b 0000000c -00000014 0000000d 0000000e 0000000f 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/stat/ndisc_cache -Lines: 3 -entries allocs destroys hash_grows lookups hits res_failed rcv_probes_mcast rcv_probes_ucast periodic_gc_runs forced_gc_runs unresolved_discards table_fulls -00000024 000000f0 000000f1 000000f2 000000f3 000000f4 000000f5 000000f6 000000f7 000000f8 000000f9 000000fa 000000fb -00000024 000000fc 000000fd 000000fe 000000ff 00000100 00000101 00000102 00000103 00000104 00000105 00000106 00000107 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/tcp -Lines: 4 - sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - 0: 0500000A:0016 00000000:0000 0A 00000000:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 1: 00000000:0016 00000000:0000 0A 00000001:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 2: 00000000:0016 00000000:0000 0A 00000001:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/tcp6 -Lines: 3 - sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops - 1315: 00000000000000000000000000000000:14EB 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 981 0 21040 2 0000000013726323 0 - 6073: 000080FE00000000FFADE15609667CFE:C781 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 11337031 2 00000000b9256fdd 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/udp -Lines: 4 - sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode - 0: 0500000A:0016 00000000:0000 0A 00000000:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 1: 00000000:0016 00000000:0000 0A 00000001:00000000 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 - 2: 00000000:0016 00000000:0000 0A 00000001:00000001 00:00000000 00000000 0 0 2740 1 ffff88003d3af3c0 100 0 0 10 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/udp6 -Lines: 3 - sl local_address remote_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode ref pointer drops - 1315: 00000000000000000000000000000000:14EB 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 981 0 21040 2 0000000013726323 0 - 6073: 000080FE00000000FFADE15609667CFE:C781 00000000000000000000000000000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 11337031 2 00000000b9256fdd 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/udp_broken -Lines: 2 - sl local_address rem_address st - 1: 00000000:0016 00000000:0000 0A -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/unix -Lines: 6 -Num RefCount Protocol Flags Type St Inode Path -0000000000000000: 00000002 00000000 00010000 0001 01 3442596 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 0000000a 00000000 00010000 0005 01 10061 /run/udev/control -0000000000000000: 00000007 00000000 00000000 0002 01 12392 /dev/log -0000000000000000: 00000003 00000000 00000000 0001 03 4787297 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 00000003 00000000 00000000 0001 03 5091797 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/unix_without_inode -Lines: 6 -Num RefCount Protocol Flags Type St Path -0000000000000000: 00000002 00000000 00010000 0001 01 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 0000000a 00000000 00010000 0005 01 /run/udev/control -0000000000000000: 00000007 00000000 00000000 0002 01 /dev/log -0000000000000000: 00000003 00000000 00000000 0001 03 /var/run/postgresql/.s.PGSQL.5432 -0000000000000000: 00000003 00000000 00000000 0001 03 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/net/xfrm_stat -Lines: 28 -XfrmInError 1 -XfrmInBufferError 2 -XfrmInHdrError 4 -XfrmInNoStates 3 -XfrmInStateProtoError 40 -XfrmInStateModeError 100 -XfrmInStateSeqError 6000 -XfrmInStateExpired 4 -XfrmInStateMismatch 23451 -XfrmInStateInvalid 55555 -XfrmInTmplMismatch 51 -XfrmInNoPols 65432 -XfrmInPolBlock 100 -XfrmInPolError 10000 -XfrmOutError 1000000 -XfrmOutBundleGenError 43321 -XfrmOutBundleCheckError 555 -XfrmOutNoStates 869 -XfrmOutStateProtoError 4542 -XfrmOutStateModeError 4 -XfrmOutStateSeqError 543 -XfrmOutStateExpired 565 -XfrmOutPolBlock 43456 -XfrmOutPolDead 7656 -XfrmOutPolError 1454 -XfrmFwdHdrError 6654 -XfrmOutStateInvalid 28765 -XfrmAcquireError 24532 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/pressure -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/pressure/cpu -Lines: 1 -some avg10=0.10 avg60=2.00 avg300=3.85 total=15 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/pressure/io -Lines: 2 -some avg10=0.10 avg60=2.00 avg300=3.85 total=15 -full avg10=0.20 avg60=3.00 avg300=4.95 total=25 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/pressure/memory -Lines: 2 -some avg10=0.10 avg60=2.00 avg300=3.85 total=15 -full avg10=0.20 avg60=3.00 avg300=4.95 total=25 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/schedstat -Lines: 6 -version 15 -timestamp 15819019232 -cpu0 498494191 0 3533438552 2553969831 3853684107 2465731542 2045936778163039 343796328169361 4767485306 -domain0 00000000,00000003 212499247 210112015 1861015 1860405436 536440 369895 32599 210079416 25368550 24241256 384652 927363878 807233 6366 1647 24239609 2122447165 1886868564 121112060 2848625533 125678146 241025 1032026 1885836538 2545 12 2533 0 0 0 0 0 0 1387952561 21076581 0 -cpu1 518377256 0 4155211005 2778589869 10466382 2867629021 1904686152592476 364107263788241 5145567945 -domain0 00000000,00000003 217653037 215526982 1577949 1580427380 557469 393576 28538 215498444 28721913 27662819 371153 870843407 745912 5523 1639 27661180 2331056874 2107732788 111442342 652402556 123615235 196159 1045245 2106687543 2400 3 2397 0 0 0 0 0 0 1437804657 26220076 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/self -SymlinkTo: 26231 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/slabinfo -Lines: 302 -slabinfo - version: 2.1 -# name : tunables : slabdata -pid_3 375 532 576 28 4 : tunables 0 0 0 : slabdata 19 19 0 -pid_2 3 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -nvidia_p2p_page_cache 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -nvidia_pte_cache 9022 9152 368 22 2 : tunables 0 0 0 : slabdata 416 416 0 -nvidia_stack_cache 321 326 12624 2 8 : tunables 0 0 0 : slabdata 163 163 0 -kvm_async_pf 0 0 472 34 4 : tunables 0 0 0 : slabdata 0 0 0 -kvm_vcpu 0 0 15552 2 8 : tunables 0 0 0 : slabdata 0 0 0 -kvm_mmu_page_header 0 0 504 32 4 : tunables 0 0 0 : slabdata 0 0 0 -pte_list_desc 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -x86_emulator 0 0 3024 10 8 : tunables 0 0 0 : slabdata 0 0 0 -x86_fpu 0 0 4608 7 8 : tunables 0 0 0 : slabdata 0 0 0 -iwl_cmd_pool:0000:04:00.0 0 128 512 32 4 : tunables 0 0 0 : slabdata 4 4 0 -ext4_groupinfo_4k 3719 3740 480 34 4 : tunables 0 0 0 : slabdata 110 110 0 -bio-6 32 75 640 25 4 : tunables 0 0 0 : slabdata 3 3 0 -bio-5 16 48 1344 24 8 : tunables 0 0 0 : slabdata 2 2 0 -bio-4 17 92 1408 23 8 : tunables 0 0 0 : slabdata 4 4 0 -fat_inode_cache 0 0 1056 31 8 : tunables 0 0 0 : slabdata 0 0 0 -fat_cache 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -ovl_aio_req 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -ovl_inode 0 0 1000 32 8 : tunables 0 0 0 : slabdata 0 0 0 -squashfs_inode_cache 0 0 1088 30 8 : tunables 0 0 0 : slabdata 0 0 0 -fuse_request 0 0 472 34 4 : tunables 0 0 0 : slabdata 0 0 0 -fuse_inode 0 0 1152 28 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_dqtrx 0 0 864 37 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_dquot 0 0 832 39 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_buf 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_bui_item 0 0 544 30 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_bud_item 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_cui_item 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_cud_item 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_rui_item 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_rud_item 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_icr 0 0 520 31 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_ili 0 0 528 31 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_inode 0 0 1344 24 8 : tunables 0 0 0 : slabdata 0 0 0 -xfs_efi_item 0 0 768 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_efd_item 0 0 776 21 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_buf_item 0 0 608 26 4 : tunables 0 0 0 : slabdata 0 0 0 -xf_trans 0 0 568 28 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_ifork 0 0 376 21 2 : tunables 0 0 0 : slabdata 0 0 0 -xfs_da_state 0 0 816 20 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_btree_cur 0 0 560 29 4 : tunables 0 0 0 : slabdata 0 0 0 -xfs_bmap_free_item 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -xfs_log_ticket 0 0 520 31 4 : tunables 0 0 0 : slabdata 0 0 0 -nfs_direct_cache 0 0 560 29 4 : tunables 0 0 0 : slabdata 0 0 0 -nfs_commit_data 4 28 1152 28 8 : tunables 0 0 0 : slabdata 1 1 0 -nfs_write_data 32 50 1280 25 8 : tunables 0 0 0 : slabdata 2 2 0 -nfs_read_data 0 0 1280 25 8 : tunables 0 0 0 : slabdata 0 0 0 -nfs_inode_cache 0 0 1408 23 8 : tunables 0 0 0 : slabdata 0 0 0 -nfs_page 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -rpc_inode_cache 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -rpc_buffers 8 13 2496 13 8 : tunables 0 0 0 : slabdata 1 1 0 -rpc_tasks 8 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -fscache_cookie_jar 1 35 464 35 4 : tunables 0 0 0 : slabdata 1 1 0 -jfs_mp 32 35 464 35 4 : tunables 0 0 0 : slabdata 1 1 0 -jfs_ip 0 0 1592 20 8 : tunables 0 0 0 : slabdata 0 0 0 -reiser_inode_cache 0 0 1096 29 8 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_end_io_wq 0 0 464 35 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_prelim_ref 0 0 424 38 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_extent_op 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_data_ref 0 0 448 36 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_tree_ref 0 0 440 37 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_ref_head 0 0 480 34 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_inode_defrag 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_delayed_node 0 0 648 25 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_ordered_extent 0 0 752 21 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_extent_map 0 0 480 34 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_extent_state 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -bio-3 35 92 704 23 4 : tunables 0 0 0 : slabdata 4 4 0 -btrfs_extent_buffer 0 0 600 27 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_free_space_bitmap 0 0 12288 2 8 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_free_space 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_path 0 0 448 36 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_trans_handle 0 0 440 37 4 : tunables 0 0 0 : slabdata 0 0 0 -btrfs_inode 0 0 1496 21 8 : tunables 0 0 0 : slabdata 0 0 0 -ext4_inode_cache 84136 84755 1400 23 8 : tunables 0 0 0 : slabdata 3685 3685 0 -ext4_free_data 22 80 392 20 2 : tunables 0 0 0 : slabdata 4 4 0 -ext4_allocation_context 0 70 464 35 4 : tunables 0 0 0 : slabdata 2 2 0 -ext4_prealloc_space 24 74 440 37 4 : tunables 0 0 0 : slabdata 2 2 0 -ext4_system_zone 267 273 376 21 2 : tunables 0 0 0 : slabdata 13 13 0 -ext4_io_end_vec 0 88 368 22 2 : tunables 0 0 0 : slabdata 4 4 0 -ext4_io_end 0 80 400 20 2 : tunables 0 0 0 : slabdata 4 4 0 -ext4_bio_post_read_ctx 128 147 384 21 2 : tunables 0 0 0 : slabdata 7 7 0 -ext4_pending_reservation 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -ext4_extent_status 79351 79422 376 21 2 : tunables 0 0 0 : slabdata 3782 3782 0 -jbd2_transaction_s 44 100 640 25 4 : tunables 0 0 0 : slabdata 4 4 0 -jbd2_inode 6785 6840 400 20 2 : tunables 0 0 0 : slabdata 342 342 0 -jbd2_journal_handle 0 80 392 20 2 : tunables 0 0 0 : slabdata 4 4 0 -jbd2_journal_head 824 1944 448 36 4 : tunables 0 0 0 : slabdata 54 54 0 -jbd2_revoke_table_s 4 23 352 23 2 : tunables 0 0 0 : slabdata 1 1 0 -jbd2_revoke_record_s 0 156 416 39 4 : tunables 0 0 0 : slabdata 4 4 0 -ext2_inode_cache 0 0 1144 28 8 : tunables 0 0 0 : slabdata 0 0 0 -mbcache 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -dm_thin_new_mapping 0 152 424 38 4 : tunables 0 0 0 : slabdata 4 4 0 -dm_snap_pending_exception 0 0 464 35 4 : tunables 0 0 0 : slabdata 0 0 0 -dm_exception 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dm_dirty_log_flush_entry 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dm_bio_prison_cell_v2 0 0 432 37 4 : tunables 0 0 0 : slabdata 0 0 0 -dm_bio_prison_cell 0 148 432 37 4 : tunables 0 0 0 : slabdata 4 4 0 -kcopyd_job 0 8 3648 8 8 : tunables 0 0 0 : slabdata 1 1 0 -io 0 32 512 32 4 : tunables 0 0 0 : slabdata 1 1 0 -dm_uevent 0 0 3224 10 8 : tunables 0 0 0 : slabdata 0 0 0 -dax_cache 1 28 1152 28 8 : tunables 0 0 0 : slabdata 1 1 0 -aic94xx_ascb 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -aic94xx_dma_token 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -asd_sas_event 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -sas_task 0 0 704 23 4 : tunables 0 0 0 : slabdata 0 0 0 -qla2xxx_srbs 0 0 832 39 8 : tunables 0 0 0 : slabdata 0 0 0 -sd_ext_cdb 2 22 368 22 2 : tunables 0 0 0 : slabdata 1 1 0 -scsi_sense_cache 258 288 512 32 4 : tunables 0 0 0 : slabdata 9 9 0 -virtio_scsi_cmd 64 75 640 25 4 : tunables 0 0 0 : slabdata 3 3 0 -L2TP/IPv6 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -L2TP/IP 0 0 1408 23 8 : tunables 0 0 0 : slabdata 0 0 0 -ip6-frags 0 0 520 31 4 : tunables 0 0 0 : slabdata 0 0 0 -fib6_nodes 5 32 512 32 4 : tunables 0 0 0 : slabdata 1 1 0 -ip6_dst_cache 4 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -ip6_mrt_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -PINGv6 0 0 1600 20 8 : tunables 0 0 0 : slabdata 0 0 0 -RAWv6 25 40 1600 20 8 : tunables 0 0 0 : slabdata 2 2 0 -UDPLITEv6 0 0 1728 18 8 : tunables 0 0 0 : slabdata 0 0 0 -UDPv6 3 54 1728 18 8 : tunables 0 0 0 : slabdata 3 3 0 -tw_sock_TCPv6 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -request_sock_TCPv6 0 0 632 25 4 : tunables 0 0 0 : slabdata 0 0 0 -TCPv6 0 33 2752 11 8 : tunables 0 0 0 : slabdata 3 3 0 -uhci_urb_priv 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -sgpool-128 2 14 4544 7 8 : tunables 0 0 0 : slabdata 2 2 0 -sgpool-64 2 13 2496 13 8 : tunables 0 0 0 : slabdata 1 1 0 -sgpool-32 2 44 1472 22 8 : tunables 0 0 0 : slabdata 2 2 0 -sgpool-16 2 68 960 34 8 : tunables 0 0 0 : slabdata 2 2 0 -sgpool-8 2 46 704 23 4 : tunables 0 0 0 : slabdata 2 2 0 -btree_node 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -bfq_io_cq 0 0 488 33 4 : tunables 0 0 0 : slabdata 0 0 0 -bfq_queue 0 0 848 38 8 : tunables 0 0 0 : slabdata 0 0 0 -mqueue_inode_cache 1 24 1344 24 8 : tunables 0 0 0 : slabdata 1 1 0 -isofs_inode_cache 0 0 968 33 8 : tunables 0 0 0 : slabdata 0 0 0 -io_kiocb 0 0 640 25 4 : tunables 0 0 0 : slabdata 0 0 0 -kioctx 0 30 1088 30 8 : tunables 0 0 0 : slabdata 1 1 0 -aio_kiocb 0 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -userfaultfd_ctx_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -fanotify_path_event 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -fanotify_fid_event 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -fsnotify_mark 0 0 408 20 2 : tunables 0 0 0 : slabdata 0 0 0 -dnotify_mark 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -dnotify_struct 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dio 0 0 1088 30 8 : tunables 0 0 0 : slabdata 0 0 0 -bio-2 4 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -fasync_cache 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -audit_tree_mark 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -pid_namespace 30 34 480 34 4 : tunables 0 0 0 : slabdata 1 1 0 -posix_timers_cache 0 27 592 27 4 : tunables 0 0 0 : slabdata 1 1 0 -iommu_devinfo 24 32 512 32 4 : tunables 0 0 0 : slabdata 1 1 0 -iommu_domain 10 10 3264 10 8 : tunables 0 0 0 : slabdata 1 1 0 -iommu_iova 8682 8748 448 36 4 : tunables 0 0 0 : slabdata 243 243 0 -UNIX 529 814 1472 22 8 : tunables 0 0 0 : slabdata 37 37 0 -ip4-frags 0 0 536 30 4 : tunables 0 0 0 : slabdata 0 0 0 -ip_mrt_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -UDP-Lite 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -tcp_bind_bucket 7 128 512 32 4 : tunables 0 0 0 : slabdata 4 4 0 -inet_peer_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -xfrm_dst_cache 0 0 704 23 4 : tunables 0 0 0 : slabdata 0 0 0 -xfrm_state 0 0 1152 28 8 : tunables 0 0 0 : slabdata 0 0 0 -ip_fib_trie 7 21 384 21 2 : tunables 0 0 0 : slabdata 1 1 0 -ip_fib_alias 9 20 392 20 2 : tunables 0 0 0 : slabdata 1 1 0 -ip_dst_cache 27 84 576 28 4 : tunables 0 0 0 : slabdata 3 3 0 -PING 0 0 1408 23 8 : tunables 0 0 0 : slabdata 0 0 0 -RAW 32 46 1408 23 8 : tunables 0 0 0 : slabdata 2 2 0 -UDP 11 168 1536 21 8 : tunables 0 0 0 : slabdata 8 8 0 -tw_sock_TCP 1 56 576 28 4 : tunables 0 0 0 : slabdata 2 2 0 -request_sock_TCP 0 25 632 25 4 : tunables 0 0 0 : slabdata 1 1 0 -TCP 10 60 2624 12 8 : tunables 0 0 0 : slabdata 5 5 0 -hugetlbfs_inode_cache 2 35 928 35 8 : tunables 0 0 0 : slabdata 1 1 0 -dquot 0 0 640 25 4 : tunables 0 0 0 : slabdata 0 0 0 -bio-1 32 46 704 23 4 : tunables 0 0 0 : slabdata 2 2 0 -eventpoll_pwq 409 600 408 20 2 : tunables 0 0 0 : slabdata 30 30 0 -eventpoll_epi 408 672 576 28 4 : tunables 0 0 0 : slabdata 24 24 0 -inotify_inode_mark 58 195 416 39 4 : tunables 0 0 0 : slabdata 5 5 0 -scsi_data_buffer 0 0 360 22 2 : tunables 0 0 0 : slabdata 0 0 0 -bio_crypt_ctx 128 147 376 21 2 : tunables 0 0 0 : slabdata 7 7 0 -request_queue 29 39 2408 13 8 : tunables 0 0 0 : slabdata 3 3 0 -blkdev_ioc 81 148 440 37 4 : tunables 0 0 0 : slabdata 4 4 0 -bio-0 125 200 640 25 4 : tunables 0 0 0 : slabdata 8 8 0 -biovec-max 166 196 4544 7 8 : tunables 0 0 0 : slabdata 28 28 0 -biovec-128 0 52 2496 13 8 : tunables 0 0 0 : slabdata 4 4 0 -biovec-64 0 88 1472 22 8 : tunables 0 0 0 : slabdata 4 4 0 -biovec-16 0 92 704 23 4 : tunables 0 0 0 : slabdata 4 4 0 -bio_integrity_payload 4 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -khugepaged_mm_slot 59 180 448 36 4 : tunables 0 0 0 : slabdata 5 5 0 -ksm_mm_slot 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -ksm_stable_node 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -ksm_rmap_item 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -user_namespace 2 37 864 37 8 : tunables 0 0 0 : slabdata 1 1 0 -uid_cache 5 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-256 1 13 2496 13 8 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-128 1 22 1472 22 8 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-16 1 28 576 28 4 : tunables 0 0 0 : slabdata 1 1 0 -dmaengine-unmap-2 1 36 448 36 4 : tunables 0 0 0 : slabdata 1 1 0 -audit_buffer 0 22 360 22 2 : tunables 0 0 0 : slabdata 1 1 0 -sock_inode_cache 663 1170 1216 26 8 : tunables 0 0 0 : slabdata 45 45 0 -skbuff_ext_cache 0 0 576 28 4 : tunables 0 0 0 : slabdata 0 0 0 -skbuff_fclone_cache 1 72 896 36 8 : tunables 0 0 0 : slabdata 2 2 0 -skbuff_head_cache 3 650 640 25 4 : tunables 0 0 0 : slabdata 26 26 0 -configfs_dir_cache 7 38 424 38 4 : tunables 0 0 0 : slabdata 1 1 0 -file_lock_cache 27 116 552 29 4 : tunables 0 0 0 : slabdata 4 4 0 -file_lock_ctx 106 120 392 20 2 : tunables 0 0 0 : slabdata 6 6 0 -fsnotify_mark_connector 52 66 368 22 2 : tunables 0 0 0 : slabdata 3 3 0 -net_namespace 1 6 5312 6 8 : tunables 0 0 0 : slabdata 1 1 0 -task_delay_info 784 1560 416 39 4 : tunables 0 0 0 : slabdata 40 40 0 -taskstats 45 92 688 23 4 : tunables 0 0 0 : slabdata 4 4 0 -proc_dir_entry 678 682 528 31 4 : tunables 0 0 0 : slabdata 22 22 0 -pde_opener 0 189 376 21 2 : tunables 0 0 0 : slabdata 9 9 0 -proc_inode_cache 7150 8250 992 33 8 : tunables 0 0 0 : slabdata 250 250 0 -seq_file 60 735 456 35 4 : tunables 0 0 0 : slabdata 21 21 0 -sigqueue 0 156 416 39 4 : tunables 0 0 0 : slabdata 4 4 0 -bdev_cache 36 78 1216 26 8 : tunables 0 0 0 : slabdata 3 3 0 -shmem_inode_cache 1599 2208 1016 32 8 : tunables 0 0 0 : slabdata 69 69 0 -kernfs_iattrs_cache 1251 1254 424 38 4 : tunables 0 0 0 : slabdata 33 33 0 -kernfs_node_cache 52898 52920 464 35 4 : tunables 0 0 0 : slabdata 1512 1512 0 -mnt_cache 42 46 704 23 4 : tunables 0 0 0 : slabdata 2 2 0 -filp 4314 6371 704 23 4 : tunables 0 0 0 : slabdata 277 277 0 -inode_cache 28695 29505 920 35 8 : tunables 0 0 0 : slabdata 843 843 0 -dentry 166069 169074 528 31 4 : tunables 0 0 0 : slabdata 5454 5454 0 -names_cache 0 35 4544 7 8 : tunables 0 0 0 : slabdata 5 5 0 -hashtab_node 0 0 360 22 2 : tunables 0 0 0 : slabdata 0 0 0 -ebitmap_node 0 0 400 20 2 : tunables 0 0 0 : slabdata 0 0 0 -avtab_extended_perms 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -avtab_node 0 0 360 22 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_xperms_data 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_xperms_decision_node 0 0 384 21 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_xperms_node 0 0 392 20 2 : tunables 0 0 0 : slabdata 0 0 0 -avc_node 37 40 408 20 2 : tunables 0 0 0 : slabdata 2 2 0 -iint_cache 0 0 448 36 4 : tunables 0 0 0 : slabdata 0 0 0 -lsm_inode_cache 122284 122340 392 20 2 : tunables 0 0 0 : slabdata 6117 6117 0 -lsm_file_cache 4266 4485 352 23 2 : tunables 0 0 0 : slabdata 195 195 0 -key_jar 8 25 640 25 4 : tunables 0 0 0 : slabdata 1 1 0 -buffer_head 255622 257076 440 37 4 : tunables 0 0 0 : slabdata 6948 6948 0 -uts_namespace 0 0 776 21 4 : tunables 0 0 0 : slabdata 0 0 0 -nsproxy 31 40 408 20 2 : tunables 0 0 0 : slabdata 2 2 0 -vm_area_struct 39115 43214 528 31 4 : tunables 0 0 0 : slabdata 1394 1394 0 -mm_struct 96 529 1408 23 8 : tunables 0 0 0 : slabdata 23 23 0 -fs_cache 102 756 448 36 4 : tunables 0 0 0 : slabdata 21 21 0 -files_cache 102 588 1152 28 8 : tunables 0 0 0 : slabdata 21 21 0 -signal_cache 266 672 1536 21 8 : tunables 0 0 0 : slabdata 32 32 0 -sighand_cache 266 507 2496 13 8 : tunables 0 0 0 : slabdata 39 39 0 -task_struct 783 963 10240 3 8 : tunables 0 0 0 : slabdata 321 321 0 -cred_jar 364 952 576 28 4 : tunables 0 0 0 : slabdata 34 34 0 -anon_vma_chain 63907 67821 416 39 4 : tunables 0 0 0 : slabdata 1739 1739 0 -anon_vma 25891 28899 416 39 4 : tunables 0 0 0 : slabdata 741 741 0 -pid 408 992 512 32 4 : tunables 0 0 0 : slabdata 31 31 0 -Acpi-Operand 6682 6740 408 20 2 : tunables 0 0 0 : slabdata 337 337 0 -Acpi-ParseExt 0 39 416 39 4 : tunables 0 0 0 : slabdata 1 1 0 -Acpi-Parse 0 80 392 20 2 : tunables 0 0 0 : slabdata 4 4 0 -Acpi-State 0 78 416 39 4 : tunables 0 0 0 : slabdata 2 2 0 -Acpi-Namespace 3911 3948 384 21 2 : tunables 0 0 0 : slabdata 188 188 0 -trace_event_file 2638 2660 424 38 4 : tunables 0 0 0 : slabdata 70 70 0 -ftrace_event_field 6592 6594 384 21 2 : tunables 0 0 0 : slabdata 314 314 0 -pool_workqueue 41 64 1024 32 8 : tunables 0 0 0 : slabdata 2 2 0 -radix_tree_node 21638 24045 912 35 8 : tunables 0 0 0 : slabdata 687 687 0 -task_group 48 78 1216 26 8 : tunables 0 0 0 : slabdata 3 3 0 -vmap_area 4411 4680 400 20 2 : tunables 0 0 0 : slabdata 234 234 0 -dma-kmalloc-8k 0 0 24576 1 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-4k 0 0 12288 2 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-2k 0 0 6144 5 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-1k 0 0 3072 10 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-512 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-256 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-128 0 0 640 25 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-64 0 0 512 32 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-32 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-16 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-8 0 0 344 23 2 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-192 0 0 528 31 4 : tunables 0 0 0 : slabdata 0 0 0 -dma-kmalloc-96 0 0 432 37 4 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-8k 0 0 24576 1 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-4k 0 0 12288 2 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-2k 0 0 6144 5 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-1k 0 0 3072 10 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-512 0 0 1536 21 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-256 0 0 1024 32 8 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-192 0 0 528 31 4 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-128 31 75 640 25 4 : tunables 0 0 0 : slabdata 3 3 0 -kmalloc-rcl-96 3371 3626 432 37 4 : tunables 0 0 0 : slabdata 98 98 0 -kmalloc-rcl-64 2080 2272 512 32 4 : tunables 0 0 0 : slabdata 71 71 0 -kmalloc-rcl-32 0 0 416 39 4 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-16 0 0 368 22 2 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-rcl-8 0 0 344 23 2 : tunables 0 0 0 : slabdata 0 0 0 -kmalloc-8k 133 140 24576 1 8 : tunables 0 0 0 : slabdata 140 140 0 -kmalloc-4k 403 444 12288 2 8 : tunables 0 0 0 : slabdata 222 222 0 -kmalloc-2k 2391 2585 6144 5 8 : tunables 0 0 0 : slabdata 517 517 0 -kmalloc-1k 2163 2420 3072 10 8 : tunables 0 0 0 : slabdata 242 242 0 -kmalloc-512 2972 3633 1536 21 8 : tunables 0 0 0 : slabdata 173 173 0 -kmalloc-256 1841 1856 1024 32 8 : tunables 0 0 0 : slabdata 58 58 0 -kmalloc-192 2165 2914 528 31 4 : tunables 0 0 0 : slabdata 94 94 0 -kmalloc-128 1137 1175 640 25 4 : tunables 0 0 0 : slabdata 47 47 0 -kmalloc-96 1925 2590 432 37 4 : tunables 0 0 0 : slabdata 70 70 0 -kmalloc-64 9433 10688 512 32 4 : tunables 0 0 0 : slabdata 334 334 0 -kmalloc-32 9098 10062 416 39 4 : tunables 0 0 0 : slabdata 258 258 0 -kmalloc-16 10914 10956 368 22 2 : tunables 0 0 0 : slabdata 498 498 0 -kmalloc-8 7576 7705 344 23 2 : tunables 0 0 0 : slabdata 335 335 0 -kmem_cache_node 904 928 512 32 4 : tunables 0 0 0 : slabdata 29 29 0 -kmem_cache 904 936 832 39 8 : tunables 0 0 0 : slabdata 24 24 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/stat -Lines: 16 -cpu 301854 612 111922 8979004 3552 2 3944 0 0 0 -cpu0 44490 19 21045 1087069 220 1 3410 0 0 0 -cpu1 47869 23 16474 1110787 591 0 46 0 0 0 -cpu2 46504 36 15916 1112321 441 0 326 0 0 0 -cpu3 47054 102 15683 1113230 533 0 60 0 0 0 -cpu4 28413 25 10776 1140321 217 0 8 0 0 0 -cpu5 29271 101 11586 1136270 672 0 30 0 0 0 -cpu6 29152 36 10276 1139721 319 0 29 0 0 0 -cpu7 29098 268 10164 1139282 555 0 31 0 0 0 -intr 8885917 17 0 0 0 0 0 0 0 1 79281 0 0 0 0 0 0 0 231237 0 0 0 0 250586 103 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 223424 190745 13 906 1283803 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -ctxt 38014093 -btime 1418183276 -processes 26442 -procs_running 2 -procs_blocked 1 -softirq 5057579 250191 1481983 1647 211099 186066 0 1783454 622196 12499 508444 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/swaps -Lines: 2 -Filename Type Size Used Priority -/dev/dm-2 partition 131068 176 -2 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/symlinktargets -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/README -Lines: 2 -This directory contains some empty files that are the symlinks the files in the "fd" directory point to. -They are otherwise ignored by the tests -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/abc -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/def -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/ghi -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/uvw -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/symlinktargets/xyz -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys/kernel -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys/kernel/random -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/entropy_avail -Lines: 1 -3943 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/poolsize -Lines: 1 -4096 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/urandom_min_reseed_secs -Lines: 1 -60 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/kernel/random/write_wakeup_threshold -Lines: 1 -3072 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/proc/sys/vm -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/admin_reserve_kbytes -Lines: 1 -8192 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/block_dump -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/compact_unevictable_allowed -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_background_bytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_background_ratio -Lines: 1 -10 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_bytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_expire_centisecs -Lines: 1 -3000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_ratio -Lines: 1 -20 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirty_writeback_centisecs -Lines: 1 -500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/dirtytime_expire_seconds -Lines: 1 -43200 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/drop_caches -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/extfrag_threshold -Lines: 1 -500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/hugetlb_shm_group -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/laptop_mode -Lines: 1 -5 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/legacy_va_layout -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/lowmem_reserve_ratio -Lines: 1 -256 256 32 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/max_map_count -Lines: 1 -65530 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/memory_failure_early_kill -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/memory_failure_recovery -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/min_free_kbytes -Lines: 1 -67584 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/min_slab_ratio -Lines: 1 -5 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/min_unmapped_ratio -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/mmap_min_addr -Lines: 1 -65536 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/nr_hugepages -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/nr_hugepages_mempolicy -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/nr_overcommit_hugepages -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/numa_stat -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/numa_zonelist_order -Lines: 1 -Node -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/oom_dump_tasks -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/oom_kill_allocating_task -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/overcommit_kbytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/overcommit_memory -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/overcommit_ratio -Lines: 1 -50 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/page-cluster -Lines: 1 -3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/panic_on_oom -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/percpu_pagelist_fraction -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/stat_interval -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/swappiness -Lines: 1 -60 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/user_reserve_kbytes -Lines: 1 -131072 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/vfs_cache_pressure -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/watermark_boost_factor -Lines: 1 -15000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/watermark_scale_factor -Lines: 1 -10 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/sys/vm/zone_reclaim_mode -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/proc/zoneinfo -Lines: 262 -Node 0, zone DMA - per-node stats - nr_inactive_anon 230981 - nr_active_anon 547580 - nr_inactive_file 316904 - nr_active_file 346282 - nr_unevictable 115467 - nr_slab_reclaimable 131220 - nr_slab_unreclaimable 47320 - nr_isolated_anon 0 - nr_isolated_file 0 - workingset_nodes 11627 - workingset_refault 466886 - workingset_activate 276925 - workingset_restore 84055 - workingset_nodereclaim 487 - nr_anon_pages 795576 - nr_mapped 215483 - nr_file_pages 761874 - nr_dirty 908 - nr_writeback 0 - nr_writeback_temp 0 - nr_shmem 224925 - nr_shmem_hugepages 0 - nr_shmem_pmdmapped 0 - nr_anon_transparent_hugepages 0 - nr_unstable 0 - nr_vmscan_write 12950 - nr_vmscan_immediate_reclaim 3033 - nr_dirtied 8007423 - nr_written 7752121 - nr_kernel_misc_reclaimable 0 - pages free 3952 - min 33 - low 41 - high 49 - spanned 4095 - present 3975 - managed 3956 - protection: (0, 2877, 7826, 7826, 7826) - nr_free_pages 3952 - nr_zone_inactive_anon 0 - nr_zone_active_anon 0 - nr_zone_inactive_file 0 - nr_zone_active_file 0 - nr_zone_unevictable 0 - nr_zone_write_pending 0 - nr_mlock 0 - nr_page_table_pages 0 - nr_kernel_stack 0 - nr_bounce 0 - nr_zspages 0 - nr_free_cma 0 - numa_hit 1 - numa_miss 0 - numa_foreign 0 - numa_interleave 0 - numa_local 1 - numa_other 0 - pagesets - cpu: 0 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 1 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 2 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 3 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 4 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 5 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 6 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - cpu: 7 - count: 0 - high: 0 - batch: 1 - vm stats threshold: 8 - node_unreclaimable: 0 - start_pfn: 1 -Node 0, zone DMA32 - pages free 204252 - min 19510 - low 21059 - high 22608 - spanned 1044480 - present 759231 - managed 742806 - protection: (0, 0, 4949, 4949, 4949) - nr_free_pages 204252 - nr_zone_inactive_anon 118558 - nr_zone_active_anon 106598 - nr_zone_inactive_file 75475 - nr_zone_active_file 70293 - nr_zone_unevictable 66195 - nr_zone_write_pending 64 - nr_mlock 4 - nr_page_table_pages 1756 - nr_kernel_stack 2208 - nr_bounce 0 - nr_zspages 0 - nr_free_cma 0 - numa_hit 113952967 - numa_miss 0 - numa_foreign 0 - numa_interleave 0 - numa_local 113952967 - numa_other 0 - pagesets - cpu: 0 - count: 345 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 1 - count: 356 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 2 - count: 325 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 3 - count: 346 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 4 - count: 321 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 5 - count: 316 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 6 - count: 373 - high: 378 - batch: 63 - vm stats threshold: 48 - cpu: 7 - count: 339 - high: 378 - batch: 63 - vm stats threshold: 48 - node_unreclaimable: 0 - start_pfn: 4096 -Node 0, zone Normal - pages free 18553 - min 11176 - low 13842 - high 16508 - spanned 1308160 - present 1308160 - managed 1268711 - protection: (0, 0, 0, 0, 0) - nr_free_pages 18553 - nr_zone_inactive_anon 112423 - nr_zone_active_anon 440982 - nr_zone_inactive_file 241429 - nr_zone_active_file 275989 - nr_zone_unevictable 49272 - nr_zone_write_pending 844 - nr_mlock 154 - nr_page_table_pages 9750 - nr_kernel_stack 15136 - nr_bounce 0 - nr_zspages 0 - nr_free_cma 0 - numa_hit 162718019 - numa_miss 0 - numa_foreign 0 - numa_interleave 26812 - numa_local 162718019 - numa_other 0 - pagesets - cpu: 0 - count: 316 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 1 - count: 366 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 2 - count: 60 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 3 - count: 256 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 4 - count: 253 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 5 - count: 159 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 6 - count: 311 - high: 378 - batch: 63 - vm stats threshold: 56 - cpu: 7 - count: 264 - high: 378 - batch: 63 - vm stats threshold: 56 - node_unreclaimable: 0 - start_pfn: 1048576 -Node 0, zone Movable - pages free 0 - min 0 - low 0 - high 0 - spanned 0 - present 0 - managed 0 - protection: (0, 0, 0, 0, 0) -Node 0, zone Device - pages free 0 - min 0 - low 0 - high 0 - spanned 0 - present 0 - managed 0 - protection: (0, 0, 0, 0, 0) -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/dm-0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/dm-0/stat -Lines: 1 -6447303 0 710266738 1529043 953216 0 31201176 4557464 0 796160 6088971 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/sda -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/sda/queue -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/add_random -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/chunk_sectors -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/dax -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_granularity -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_max_bytes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_max_hw_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/discard_zeroes_data -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/fua -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/hw_sector_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/io_poll -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/io_poll_delay -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/io_timeout -Lines: 1 -30000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/block/sda/queue/iosched -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/back_seek_max -Lines: 1 -16384 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/back_seek_penalty -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_async -Lines: 1 -250 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/fifo_expire_sync -Lines: 1 -125 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/low_latency -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/max_budget -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/slice_idle -Lines: 1 -8 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/slice_idle_us -Lines: 1 -8000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/strict_guarantees -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iosched/timeout_sync -Lines: 1 -125 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/iostats -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/logical_block_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_discard_segments -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_hw_sectors_kb -Lines: 1 -32767 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_integrity_segments -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_sectors_kb -Lines: 1 -1280 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_segment_size -Lines: 1 -65536 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/max_segments -Lines: 1 -168 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/minimum_io_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/nomerges -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/nr_requests -Lines: 1 -64 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/nr_zones -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/optimal_io_size -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/physical_block_size -Lines: 1 -512 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/read_ahead_kb -Lines: 1 -128 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/rotational -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/rq_affinity -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/scheduler -Lines: 1 -mq-deadline kyber [bfq] none -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/wbt_lat_usec -Lines: 1 -75000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/write_cache -Lines: 1 -write back -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/write_same_max_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/write_zeroes_max_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/queue/zoned -Lines: 1 -none -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/block/sda/stat -Lines: 1 -9652963 396792 759304206 412943 8422549 6731723 286915323 13947418 0 5658367 19174573 1 2 3 12 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/drm -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/drm/card0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/drm/card0/device -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/aer_dev_correctable -Lines: 9 -RxErr 0 -BadTLP 0 -BadDLLP 0 -Rollover 0 -Timeout 0 -NonFatalErr 0 -CorrIntErr 0 -HeaderOF 0 -TOTAL_ERR_COR 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/aer_dev_fatal -Lines: 19 -Undefined 0 -DLP 0 -SDES 0 -TLP 0 -FCP 0 -CmpltTO 0 -CmpltAbrt 0 -UnxCmplt 0 -RxOF 0 -MalfTLP 0 -ECRC 0 -UnsupReq 0 -ACSViol 0 -UncorrIntErr 0 -BlockedTLP 0 -AtomicOpBlocked 0 -TLPBlockedErr 0 -PoisonTLPBlocked 0 -TOTAL_ERR_FATAL 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/aer_dev_nonfatal -Lines: 19 -Undefined 0 -DLP 0 -SDES 0 -TLP 0 -FCP 0 -CmpltTO 0 -CmpltAbrt 0 -UnxCmplt 0 -RxOF 0 -MalfTLP 0 -ECRC 0 -UnsupReq 0 -ACSViol 0 -UncorrIntErr 0 -BlockedTLP 0 -AtomicOpBlocked 0 -TLPBlockedErr 0 -PoisonTLPBlocked 0 -TOTAL_ERR_NONFATAL 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/ari_enabled -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/boot_vga -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/broken_parity_status -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/class -Lines: 1 -0x030000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/consistent_dma_mask_bits -Lines: 1 -44 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/current_link_speed -Lines: 1 -8.0 GT/s PCIe -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/current_link_width -Lines: 1 -16 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/d3cold_allowed -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/device -Lines: 1 -0x687f -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/dma_mask_bits -Lines: 1 -44 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/driver_override -Lines: 1 -(null) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/gpu_busy_percent -Lines: 1 -4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/irq -Lines: 1 -95 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/local_cpulist -Lines: 1 -0-15 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/local_cpus -Lines: 1 -0000ffff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/max_link_speed -Lines: 1 -8.0 GT/s PCIe -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/max_link_width -Lines: 1 -16 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_gtt_total -Lines: 1 -8573157376 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_gtt_used -Lines: 1 -144560128 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vis_vram_total -Lines: 1 -8573157376 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vis_vram_used -Lines: 1 -1490378752 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vram_total -Lines: 1 -8573157376 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vram_used -Lines: 1 -1490378752 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/mem_info_vram_vendor -Lines: 1 -samsung -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/modalias -Lines: 1 -pci:v00001002d0000687Fsv00001043sd000004C4bc03sc00i00 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/msi_bus -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/numa_node -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pcie_bw -Lines: 1 -6641 815 256 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pcie_replay_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/power_dpm_force_performance_level -Lines: 1 -manual -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/power_dpm_state -Lines: 1 -performance -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/power_state -Lines: 1 -D0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_cur_state -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_dcefclk -Lines: 5 -0: 600Mhz * -1: 720Mhz -2: 800Mhz -3: 847Mhz -4: 900Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_mclk -Lines: 4 -0: 167Mhz * -1: 500Mhz -2: 800Mhz -3: 945Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_pcie -Lines: 2 -0: 8.0GT/s, x16 -1: 8.0GT/s, x16 * -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_sclk -Lines: 8 -0: 852Mhz * -1: 991Mhz -2: 1084Mhz -3: 1138Mhz -4: 1200Mhz -5: 1401Mhz -6: 1536Mhz -7: 1630Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_dpm_socclk -Lines: 8 -0: 600Mhz -1: 720Mhz * -2: 800Mhz -3: 847Mhz -4: 900Mhz -5: 960Mhz -6: 1028Mhz -7: 1107Mhz -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_features -Lines: 32 -Current ppfeatures: 0x0000000019a1ff4f -FEATURES BITMASK ENABLEMENT -DPM_PREFETCHER 0x0000000000000001 Y -GFXCLK_DPM 0x0000000000000002 Y -UCLK_DPM 0x0000000000000004 Y -SOCCLK_DPM 0x0000000000000008 Y -UVD_DPM 0x0000000000000010 N -VCE_DPM 0x0000000000000020 N -ULV 0x0000000000000040 Y -MP0CLK_DPM 0x0000000000000080 N -LINK_DPM 0x0000000000000100 Y -DCEFCLK_DPM 0x0000000000000200 Y -AVFS 0x0000000000000400 Y -GFXCLK_DS 0x0000000000000800 Y -SOCCLK_DS 0x0000000000001000 Y -LCLK_DS 0x0000000000002000 Y -PPT 0x0000000000004000 Y -TDC 0x0000000000008000 Y -THERMAL 0x0000000000010000 Y -GFX_PER_CU_CG 0x0000000000020000 N -RM 0x0000000000040000 N -DCEFCLK_DS 0x0000000000080000 N -ACDC 0x0000000000100000 N -VR0HOT 0x0000000000200000 Y -VR1HOT 0x0000000000400000 N -FW_CTF 0x0000000000800000 Y -LED_DISPLAY 0x0000000001000000 Y -FAN_CONTROL 0x0000000002000000 N -FAST_PPT 0x0000000004000000 N -DIDT 0x0000000008000000 Y -ACG 0x0000000010000000 Y -PCC_LIMIT 0x0000000020000000 N -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_force_state -Lines: 1 - -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_mclk_od -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_num_states -Lines: 3 -states: 2 -0 boot -1 performance -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_od_clk_voltage -Lines: 18 -OD_SCLK: -0: 852Mhz 800mV -1: 991Mhz 900mV -2: 1084Mhz 950mV -3: 1138Mhz 1000mV -4: 1200Mhz 1050mV -5: 1401Mhz 1100mV -6: 1536Mhz 1150mV -7: 1630Mhz 1200mV -OD_MCLK: -0: 167Mhz 800mV -1: 500Mhz 800mV -2: 800Mhz 950mV -3: 945Mhz 1100mV -OD_RANGE: -SCLK: 852MHz 2400MHz -MCLK: 167MHz 1500MHz -VDDC: 800mV 1200mV -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_power_profile_mode -Lines: 8 -NUM MODE_NAME BUSY_SET_POINT FPS USE_RLC_BUSY MIN_ACTIVE_LEVEL - 0 BOOTUP_DEFAULT : 70 60 0 0 - 1 3D_FULL_SCREEN*: 70 60 1 3 - 2 POWER_SAVING : 90 60 0 0 - 3 VIDEO : 70 60 0 0 - 4 VR : 70 90 0 0 - 5 COMPUTE : 30 60 0 6 - 6 CUSTOM : 0 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/pp_sclk_od -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/product_name -Lines: 1 - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/product_number -Lines: 1 - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/resource -Lines: 13 -0x0000007c00000000 0x0000007dffffffff 0x000000000014220c -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000007e00000000 0x0000007e0fffffff 0x000000000014220c -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x000000000000d000 0x000000000000d0ff 0x0000000000040101 -0x00000000fcd00000 0x00000000fcd7ffff 0x0000000000040200 -0x00000000fcd80000 0x00000000fcd9ffff 0x0000000000046200 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/revision -Lines: 1 -0xc1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/serial_number -Lines: 1 - -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/subsystem_device -Lines: 1 -0x04c4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/subsystem_vendor -Lines: 1 -0x1043 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/thermal_throttling_logging -Lines: 1 -0000:09:00.0: thermal throttling logging enabled, with interval 60 seconds -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/uevent -Lines: 6 -DRIVER=amdgpu -PCI_CLASS=30000 -PCI_ID=1002:687F -PCI_SUBSYS_ID=1043:04C4 -PCI_SLOT_NAME=0000:09:00.0 -MODALIAS=pci:v00001002d0000687Fsv00001043sd000004C4bc03sc00i00 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/unique_id -Lines: 1 -0123456789abcdef -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/vbios_version -Lines: 1 -115-D050PIL-100 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/drm/card0/device/vendor -Lines: 1 -0x1002 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/fc_host -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/fc_host/host0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/dev_loss_tmo -Lines: 1 -30 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/fabric_name -Lines: 1 -0x0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/node_name -Lines: 1 -0x2000e0071bce95f2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_id -Lines: 1 -0x000002 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_name -Lines: 1 -0x1000e0071bce95f2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_state -Lines: 1 -Online -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/port_type -Lines: 1 -Point-To-Point (direct nport connection) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/speed -Lines: 1 -16 Gbit -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/fc_host/host0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/dumped_frames -Lines: 1 -0xffffffffffffffff -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/error_frames -Lines: 1 -0x0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/fcp_packet_aborts -Lines: 1 -0x13 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/invalid_crc_count -Lines: 1 -0x2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/invalid_tx_word_count -Lines: 1 -0x8 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/link_failure_count -Lines: 1 -0x9 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_signal_count -Lines: 1 -0x11 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/loss_of_sync_count -Lines: 1 -0x10 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/nos_count -Lines: 1 -0x12 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/rx_frames -Lines: 1 -0x3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/rx_words -Lines: 1 -0x4 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/seconds_since_last_reset -Lines: 1 -0x7 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/tx_frames -Lines: 1 -0x5 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/statistics/tx_words -Lines: 1 -0x6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/supported_classes -Lines: 1 -Class 3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/supported_speeds -Lines: 1 -4 Gbit, 8 Gbit, 16 Gbit -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/fc_host/host0/symbolic_name -Lines: 1 -Emulex SN1100E2P FV12.4.270.3 DV12.4.0.0. HN:gotest. OS:Linux -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/board_id -Lines: 1 -HPE 100Gb 1-port OP101 QSFP28 x16 PCIe Gen3 with Intel Omni-Path Adapter -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/fw_ver -Lines: 1 -1.27.0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0/ports -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0/ports/1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/VL15_dropped -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/excessive_buffer_overrun_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/link_downed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/link_error_recovery -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/local_link_integrity_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_data -Lines: 1 -345091702026 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_packets -Lines: 1 -638036947 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_remote_physical_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_rcv_switch_relay_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_data -Lines: 1 -273558326543 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_discards -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_packets -Lines: 1 -568318856 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/port_xmit_wait -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/counters/symbol_error -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/phys_state -Lines: 1 -5: LinkUp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/rate -Lines: 1 -100 Gb/sec (4X EDR) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/hfi1_0/ports/1/state -Lines: 1 -4: ACTIVE -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/board_id -Lines: 1 -SM_1141000001000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/fw_ver -Lines: 1 -2.31.5050 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/hca_type -Lines: 1 -MT4099 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/VL15_dropped -Lines: 1 -0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/excessive_buffer_overrun_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/link_downed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/link_error_recovery -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/local_link_integrity_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_data -Lines: 1 -2221223609 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_packets -Lines: 1 -87169372 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_remote_physical_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_rcv_switch_relay_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_data -Lines: 1 -26509113295 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_discards -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_packets -Lines: 1 -85734114 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/port_xmit_wait -Lines: 1 -3599 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/counters/symbol_error -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/phys_state -Lines: 1 -5: LinkUp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/rate -Lines: 1 -40 Gb/sec (4X QDR) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/1/state -Lines: 1 -4: ACTIVE -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/VL15_dropped -Lines: 1 -0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/excessive_buffer_overrun_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/link_downed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/link_error_recovery -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/local_link_integrity_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_data -Lines: 1 -2460436784 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_packets -Lines: 1 -89332064 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_remote_physical_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_rcv_switch_relay_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_constraint_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_data -Lines: 1 -26540356890 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_discards -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_packets -Lines: 1 -88622850 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/port_xmit_wait -Lines: 1 -3846 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/counters/symbol_error -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/phys_state -Lines: 1 -5: LinkUp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/rate -Lines: 1 -40 Gb/sec (4X QDR) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/infiniband/mlx4_0/ports/2/state -Lines: 1 -4: ACTIVE -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/net -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/net/eth0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/addr_assign_type -Lines: 1 -3 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/addr_len -Lines: 1 -6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/address -Lines: 1 -01:01:01:01:01:01 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/broadcast -Lines: 1 -ff:ff:ff:ff:ff:ff -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier_changes -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier_down_count -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/carrier_up_count -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/dev_id -Lines: 1 -0x20 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/device -SymlinkTo: ../../../devices/pci0000:00/0000:00:1f.6/ -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/dormant -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/duplex -Lines: 1 -full -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/flags -Lines: 1 -0x1303 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/ifalias -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/ifindex -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/iflink -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/link_mode -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/mtu -Lines: 1 -1500 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/name_assign_type -Lines: 1 -2 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/netdev_group -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/operstate -Lines: 1 -up -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/phys_port_id -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/phys_port_name -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/phys_switch_id -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/speed -Lines: 1 -1000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/tx_queue_len -Lines: 1 -1000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/net/eth0/type -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/nvme -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/nvme/nvme0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/firmware_rev -Lines: 1 -1B2QEXP7 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/model -Lines: 1 -Samsung SSD 970 PRO 512GB -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/serial -Lines: 1 -S680HF8N190894I -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/nvme/nvme0/state -Lines: 1 -live -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/power_supply -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/power_supply/AC -SymlinkTo: ../../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/power_supply/BAT0 -SymlinkTo: ../../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl/enabled -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_max_power_uw -Lines: 1 -95000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_name -Lines: 1 -long_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_0_time_window_us -Lines: 1 -999424 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_max_power_uw -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_name -Lines: 1 -short_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/constraint_1_time_window_us -Lines: 1 -2440 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/enabled -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/energy_uj -Lines: 1 -240422366267 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/max_energy_range_uj -Lines: 1 -262143328850 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/name -Lines: 1 -package-0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_max_power_uw -Lines: 0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_name -Lines: 1 -long_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_power_limit_uw -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/constraint_0_time_window_us -Lines: 1 -976 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/enabled -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/energy_uj -Lines: 1 -118821284256 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/max_energy_range_uj -Lines: 1 -262143328850 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/name -Lines: 1 -core -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:0:0/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/powercap/intel-rapl:a -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_max_power_uw -Lines: 1 -95000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_name -Lines: 1 -long_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_0_time_window_us -Lines: 1 -999424 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_max_power_uw -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_name -Lines: 1 -short_term -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_power_limit_uw -Lines: 1 -4090000000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/constraint_1_time_window_us -Lines: 1 -2440 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/enabled -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/energy_uj -Lines: 1 -240422366267 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/max_energy_range_uj -Lines: 1 -262143328850 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/name -Lines: 1 -package-10 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/powercap/intel-rapl:a/uevent -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/scsi_tape -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0 -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0a -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0l -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/nst0m -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0 -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0a -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0l -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/scsi_tape/st0m -SymlinkTo: ../../devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/cooling_device0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device0/cur_state -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device0/max_state -Lines: 1 -50 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device0/type -Lines: 1 -Processor -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/cooling_device1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device1/cur_state -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device1/max_state -Lines: 1 -27 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/cooling_device1/type -Lines: 1 -intel_powerclamp -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/thermal_zone0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone0/policy -Lines: 1 -step_wise -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone0/temp -Lines: 1 -49925 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone0/type -Lines: 1 -bcm2835_thermal -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/class/thermal/thermal_zone1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/mode -Lines: 1 -enabled -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/passive -Lines: 1 -0 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/policy -Lines: 1 -step_wise -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/temp -Lines: 1 --44000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/class/thermal/thermal_zone1/type -Lines: 1 -acpitz -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/device -SymlinkTo: ../../../ACPI0003:00 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/online -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/async -Lines: 1 -disabled -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/autosuspend_delay_ms -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/control -Lines: 1 -auto -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_active_kids -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_active_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_enabled -Lines: 1 -disabled -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_status -Lines: 1 -unsupported -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_suspended_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/runtime_usage -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup -Lines: 1 -enabled -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_abort_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_active -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_active_count -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_expire_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_last_time_ms -Lines: 1 -10598 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_max_time_ms -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_prevent_sleep_time_ms -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/power/wakeup_total_time_ms -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/subsystem -SymlinkTo: ../../../../../../../../../class/power_supply -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/type -Lines: 1 -Mains -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/ACPI0003:00/power_supply/AC/uevent -Lines: 2 -POWER_SUPPLY_NAME=AC -POWER_SUPPLY_ONLINE=0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/alarm -Lines: 1 -2369000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/capacity -Lines: 1 -98 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/capacity_level -Lines: 1 -Normal -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_start_threshold -Lines: 1 -95 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/charge_stop_threshold -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/cycle_count -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/device -SymlinkTo: ../../../PNP0C0A:00 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_full -Lines: 1 -50060000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_full_design -Lines: 1 -47520000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/energy_now -Lines: 1 -49450000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/manufacturer -Lines: 1 -LGC -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/model_name -Lines: 1 -LNV-45N1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/async -Lines: 1 -disabled -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/autosuspend_delay_ms -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/control -Lines: 1 -auto -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_active_kids -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_active_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_enabled -Lines: 1 -disabled -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_status -Lines: 1 -unsupported -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_suspended_time -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power/runtime_usage -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/power_now -Lines: 1 -4830000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/present -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/serial_number -Lines: 1 -38109 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/status -Lines: 1 -Discharging -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/subsystem -SymlinkTo: ../../../../../../../../../class/power_supply -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/technology -Lines: 1 -Li-ion -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/type -Lines: 1 -Battery -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/uevent -Lines: 16 -POWER_SUPPLY_NAME=BAT0 -POWER_SUPPLY_STATUS=Discharging -POWER_SUPPLY_PRESENT=1 -POWER_SUPPLY_TECHNOLOGY=Li-ion -POWER_SUPPLY_CYCLE_COUNT=0 -POWER_SUPPLY_VOLTAGE_MIN_DESIGN=10800000 -POWER_SUPPLY_VOLTAGE_NOW=11750000 -POWER_SUPPLY_POWER_NOW=5064000 -POWER_SUPPLY_ENERGY_FULL_DESIGN=47520000 -POWER_SUPPLY_ENERGY_FULL=47390000 -POWER_SUPPLY_ENERGY_NOW=40730000 -POWER_SUPPLY_CAPACITY=85 -POWER_SUPPLY_CAPACITY_LEVEL=Normal -POWER_SUPPLY_MODEL_NAME=LNV-45N1 -POWER_SUPPLY_MANUFACTURER=LGC -POWER_SUPPLY_SERIAL_NUMBER=38109 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_min_design -Lines: 1 -10800000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:00/PNP0C09:00/PNP0C0A:00/power_supply/BAT0/voltage_now -Lines: 1 -12229000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0a/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0l/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/nst0m/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0a/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0l/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/in_flight -Lines: 1 -1EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/io_ns -Lines: 1 -9247011087720EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/other_cnt -Lines: 1 -1409EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_byte_cnt -Lines: 1 -979383912EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_cnt -Lines: 1 -3741EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/read_ns -Lines: 1 -33788355744EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/resid_cnt -Lines: 1 -19EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_byte_cnt -Lines: 1 -1496246784000EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_cnt -Lines: 1 -53772916EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:00.0/host0/port-0:0/end_device-0:0/target0:0:0/0:0:0:0/scsi_tape/st0m/stats/write_ns -Lines: 1 -5233597394395EOF -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/dirty_data -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_hits -Lines: 1 -289 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_day/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_five_minute/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_hour/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_hits -Lines: 1 -546 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata4/host3/target3:0:0/3:0:0:0/block/sdb/bcache/stats_total/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/io_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/metadata_written -Lines: 1 -512 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/priority_stats -Lines: 5 -Unused: 99% -Metadata: 0% -Average: 10473 -Sectors per Q: 64 -Quantiles: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946] -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:0d.0/ata5/host4/target4:0:0/4:0:0:0/block/sdc/bcache/written -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/pci0000:00/0000:00:1f.6 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/ari_enabled -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/broken_parity_status -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/class -Lines: 1 -0x020000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/consistent_dma_mask_bits -Lines: 1 -64 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/d3cold_allowed -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/device -Lines: 1 -0x15d7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/dma_mask_bits -Lines: 1 -64 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/driver_override -Lines: 1 -(null) -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/irq -Lines: 1 -140 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/local_cpulist -Lines: 1 -0-7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/local_cpus -Lines: 1 -ff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/modalias -Lines: 1 -pci:v00008086d000015D7sv000017AAsd0000225Abc02sc00i00 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/msi_bus -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/numa_node -Lines: 1 --1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/resource -Lines: 13 -0x00000000ec200000 0x00000000ec21ffff 0x0000000000040200 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -0x0000000000000000 0x0000000000000000 0x0000000000000000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/revision -Lines: 1 -0x21 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/subsystem_device -Lines: 1 -0x225a -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/subsystem_vendor -Lines: 1 -0x17aa -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/uevent -Lines: 6 -DRIVER=e1000e -PCI_CLASS=20000 -PCI_ID=8086:15D7 -PCI_SUBSYS_ID=17AA:225A -PCI_SLOT_NAME=0000:00:1f.6 -MODALIAS=pci:v00008086d000015D7sv000017AAsd0000225Abc02sc00i00 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/pci0000:00/0000:00:1f.6/vendor -Lines: 1 -0x8086 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/rbd -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/rbd/0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/0/name -Lines: 1 -demo -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/0/pool -Lines: 1 -iscsi-images -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/rbd/1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/1/name -Lines: 1 -wrong -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/rbd/1/pool -Lines: 1 -wrong-images -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/clocksource -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/clocksource/clocksource0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/clocksource/clocksource0/available_clocksource -Lines: 1 -tsc hpet acpi_pm -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/clocksource/clocksource0/current_clocksource -Lines: 1 -tsc -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/cpufreq -SymlinkTo: ../cpufreq/policy0 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle/core_throttle_count -Lines: 1 -10084 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle/package_throttle_count -Lines: 1 -34818 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu0/topology -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/core_id -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/core_siblings -Lines: 1 -ff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/core_siblings_list -Lines: 1 -0-7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/physical_package_id -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/thread_siblings -Lines: 1 -11 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu0/topology/thread_siblings_list -Lines: 1 -0,4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1/cpufreq -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_cur_freq -Lines: 1 -1200195 -Mode: 400 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_max_freq -Lines: 1 -3300000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_min_freq -Lines: 1 -1200000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/cpuinfo_transition_latency -Lines: 1 -4294967295 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/related_cpus -Lines: 1 -1 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_available_governors -Lines: 1 -performance powersave -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_driver -Lines: 1 -intel_pstate -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor -Lines: 1 -powersave -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq -Lines: 1 -3300000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_min_freq -Lines: 1 -1200000 -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/cpufreq/scaling_setspeed -Lines: 1 - -Mode: 664 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1/thermal_throttle -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/thermal_throttle/core_throttle_count -Lines: 1 -523 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/thermal_throttle/package_throttle_count -Lines: 1 -34818 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpu1/topology -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/core_id -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/core_siblings -Lines: 1 -ff -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/core_siblings_list -Lines: 1 -0-7 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/physical_package_id -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/thread_siblings -Lines: 1 -22 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpu1/topology/thread_siblings_list -Lines: 1 -1,5 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpufreq -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpufreq/policy0 -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/affected_cpus -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq -Lines: 1 -2400000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq -Lines: 1 -800000 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_transition_latency -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/related_cpus -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_available_governors -Lines: 1 -performance powersave -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq -Lines: 1 -1219917 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_driver -Lines: 1 -intel_pstate -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_governor -Lines: 1 -powersave -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq -Lines: 1 -2400000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq -Lines: 1 -800000 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/cpu/cpufreq/policy0/scaling_setspeed -Lines: 1 - -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/cpu/cpufreq/policy1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node -Mode: 775 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node1/vmstat -Lines: 6 -nr_free_pages 1 -nr_zone_inactive_anon 2 -nr_zone_active_anon 3 -nr_zone_inactive_file 4 -nr_zone_active_file 5 -nr_zone_unevictable 6 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/devices/system/node/node2 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/devices/system/node/node2/vmstat -Lines: 6 -nr_free_pages 7 -nr_zone_inactive_anon 8 -nr_zone_active_anon 9 -nr_zone_inactive_file 10 -nr_zone_active_file 11 -nr_zone_unevictable 12 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/average_key_size -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0 -Mode: 777 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/dirty_data -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_hits -Lines: 1 -289 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_day/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_five_minute/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_hour/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_hits -Lines: 1 -546 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/stats_total/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/bdev0/writeback_rate_debug -Lines: 7 -rate: 1.1M/sec -dirty: 20.4G -target: 20.4G -proportional: 427.5k -integral: 790.0k -change: 321.5k/sec -next io: 17ms -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/btree_cache_size -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0 -Mode: 777 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/io_errors -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/metadata_written -Lines: 1 -512 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/priority_stats -Lines: 5 -Unused: 99% -Metadata: 0% -Average: 10473 -Sectors per Q: 64 -Quantiles: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946 20946] -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache0/written -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/cache_available_percent -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/congested -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/active_journal_entries -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/btree_nodes -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/btree_read_average_duration_us -Lines: 1 -1305 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/internal/cache_read_races -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/root_usage_percent -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_hits -Lines: 1 -289 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_day/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_five_minute/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_hit_ratio -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_hour/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/bypassed -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_bypass_hits -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_bypass_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_hit_ratio -Lines: 1 -100 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_hits -Lines: 1 -546 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_miss_collisions -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_misses -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/stats_total/cache_readaheads -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/bcache/deaddd54-c735-46d5-868e-f331c5fd7c74/tree_depth -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/bytes_used -Lines: 1 -808189952 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/disk_total -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/disk_used -Lines: 1 -808189952 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/flags -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/raid0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/raid0/total_bytes -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/raid0/used_bytes -Lines: 1 -808189952 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/total_bytes -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/data/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/global_rsv_reserved -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/global_rsv_size -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_may_use -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_readonly -Lines: 1 -131072 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/bytes_used -Lines: 1 -933888 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/disk_total -Lines: 1 -2147483648 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/disk_used -Lines: 1 -1867776 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/flags -Lines: 1 -4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/raid1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/raid1/total_bytes -Lines: 1 -1073741824 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/raid1/used_bytes -Lines: 1 -933888 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/total_bytes -Lines: 1 -1073741824 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/metadata/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/bytes_used -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/disk_total -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/disk_used -Lines: 1 -32768 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/flags -Lines: 1 -2 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/raid1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/raid1/total_bytes -Lines: 1 -8388608 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/raid1/used_bytes -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/total_bytes -Lines: 1 -8388608 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/allocation/system/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/clone_alignment -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop25 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop25/size -Lines: 1 -20971520 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop26 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/devices/loop26/size -Lines: 1 -20971520 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/big_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/extended_iref -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/mixed_backref -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/features/skinny_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/label -Lines: 1 -fixture -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/metadata_uuid -Lines: 1 -0abb23a9-579b-43e6-ad30-227ef47fcb9d -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/nodesize -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/quota_override -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/0abb23a9-579b-43e6-ad30-227ef47fcb9d/sectorsize -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/bytes_used -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/disk_total -Lines: 1 -644087808 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/disk_used -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/flags -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/raid5 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/raid5/total_bytes -Lines: 1 -644087808 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/raid5/used_bytes -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/total_bytes -Lines: 1 -644087808 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/data/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/global_rsv_reserved -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/global_rsv_size -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_may_use -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_readonly -Lines: 1 -262144 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/bytes_used -Lines: 1 -114688 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/disk_total -Lines: 1 -429391872 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/disk_used -Lines: 1 -114688 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/flags -Lines: 1 -4 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/raid6 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/raid6/total_bytes -Lines: 1 -429391872 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/raid6/used_bytes -Lines: 1 -114688 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/total_bytes -Lines: 1 -429391872 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/metadata/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_may_use -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_readonly -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_reserved -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/bytes_used -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/disk_total -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/disk_used -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/flags -Lines: 1 -2 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/raid6 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/raid6/total_bytes -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/raid6/used_bytes -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/total_bytes -Lines: 1 -16777216 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/allocation/system/total_bytes_pinned -Lines: 1 -0 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/clone_alignment -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop22 -SymlinkTo: ../../../../devices/virtual/block/loop22 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop23 -SymlinkTo: ../../../../devices/virtual/block/loop23 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop24 -SymlinkTo: ../../../../devices/virtual/block/loop24 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/devices/loop25 -SymlinkTo: ../../../../devices/virtual/block/loop25 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/big_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/extended_iref -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/mixed_backref -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/raid56 -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/features/skinny_metadata -Lines: 1 -1 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/label -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/metadata_uuid -Lines: 1 -7f07c59f-6136-449c-ab87-e1cf2328731b -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/nodesize -Lines: 1 -16384 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/quota_override -Lines: 1 -0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/btrfs/7f07c59f-6136-449c-ab87-e1cf2328731b/sectorsize -Lines: 1 -4096 -Mode: 444 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sda1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sda1/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/xfs/sda1/stats/stats -Lines: 1 -extent_alloc 1 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sdb1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/fs/xfs/sdb1/stats -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/fs/xfs/sdb1/stats/stats -Lines: 1 -extent_alloc 2 0 0 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/fileio_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/fileio_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/fileio_1/file_lio_1G/udev_path -Lines: 1 -/home/iscsi/file_back_1G -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/iblock_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/iblock_0/block_lio_rbd1/udev_path -Lines: 1 -/dev/rbd1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rbd_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rbd_0/iscsi-images-demo/udev_path -Lines: 1 -/dev/rbd/iscsi-images/demo -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rd_mcp_119 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/core/rd_mcp_119/ramdisk_lio_1G/udev_path -Lines: 0 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/7f4a4eb56d -SymlinkTo: ../../../../../../target/core/rd_mcp_119/ramdisk_lio_1G -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -204950 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -10325 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.8888bbbbddd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -40325 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/795b7c7026 -SymlinkTo: ../../../../../../target/core/iblock_0/block_lio_rbd1 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -104950 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -20095 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2003-01.org.linux-iscsi.osd1.x8664:sn.abcd1abcd2ab/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -71235 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/fff5e16686 -SymlinkTo: ../../../../../../target/core/fileio_1/file_lio_1G -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -301950 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -10195 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:dev.rbd0/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -30195 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/enable -Lines: 1 -1 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0 -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/eba1edf893 -SymlinkTo: ../../../../../../target/core/rbd_0/iscsi-images-demo -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Directory: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port -Mode: 755 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/in_cmds -Lines: 1 -1234 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/read_mbytes -Lines: 1 -1504 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Path: fixtures/sys/kernel/config/target/iscsi/iqn.2016-11.org.linux-iscsi.igw.x86:sn.ramdemo/tpgt_1/lun/lun_0/statistics/scsi_tgt_port/write_mbytes -Lines: 1 -4733 -Mode: 644 -# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/vendor/github.com/prometheus/procfs/internal/fs/fs.go b/vendor/github.com/prometheus/procfs/internal/fs/fs.go index 0040753b1..3c18c7610 100644 --- a/vendor/github.com/prometheus/procfs/internal/fs/fs.go +++ b/vendor/github.com/prometheus/procfs/internal/fs/fs.go @@ -26,7 +26,7 @@ const ( // DefaultSysMountPoint is the common mount point of the sys filesystem. DefaultSysMountPoint = "/sys" - // DefaultConfigfsMountPoint is the common mount point of the configfs + // DefaultConfigfsMountPoint is the common mount point of the configfs. DefaultConfigfsMountPoint = "/sys/kernel/config" ) diff --git a/vendor/github.com/prometheus/procfs/internal/util/parse.go b/vendor/github.com/prometheus/procfs/internal/util/parse.go index 22cb07a6b..b030951fa 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/parse.go +++ b/vendor/github.com/prometheus/procfs/internal/util/parse.go @@ -14,7 +14,7 @@ package util import ( - "io/ioutil" + "os" "strconv" "strings" ) @@ -66,7 +66,7 @@ func ParsePInt64s(ss []string) ([]*int64, error) { // ReadUintFromFile reads a file and attempts to parse a uint64 from it. func ReadUintFromFile(path string) (uint64, error) { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return 0, err } @@ -75,7 +75,7 @@ func ReadUintFromFile(path string) (uint64, error) { // ReadIntFromFile reads a file and attempts to parse a int64 from it. func ReadIntFromFile(path string) (int64, error) { - data, err := ioutil.ReadFile(path) + data, err := os.ReadFile(path) if err != nil { return 0, err } diff --git a/vendor/github.com/prometheus/procfs/internal/util/readfile.go b/vendor/github.com/prometheus/procfs/internal/util/readfile.go index 8051161b2..71b7a70eb 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/readfile.go +++ b/vendor/github.com/prometheus/procfs/internal/util/readfile.go @@ -15,17 +15,16 @@ package util import ( "io" - "io/ioutil" "os" ) -// ReadFileNoStat uses ioutil.ReadAll to read contents of entire file. -// This is similar to ioutil.ReadFile but without the call to os.Stat, because +// ReadFileNoStat uses io.ReadAll to read contents of entire file. +// This is similar to os.ReadFile but without the call to os.Stat, because // many files in /proc and /sys report incorrect file sizes (either 0 or 4096). -// Reads a max file size of 512kB. For files larger than this, a scanner +// Reads a max file size of 1024kB. For files larger than this, a scanner // should be used. func ReadFileNoStat(filename string) ([]byte, error) { - const maxBufferSize = 1024 * 512 + const maxBufferSize = 1024 * 1024 f, err := os.Open(filename) if err != nil { @@ -34,5 +33,5 @@ func ReadFileNoStat(filename string) ([]byte, error) { defer f.Close() reader := io.LimitReader(f, maxBufferSize) - return ioutil.ReadAll(reader) + return io.ReadAll(reader) } diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go index c07de0b6c..1ab875cee 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go +++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile.go @@ -11,7 +11,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux,!appengine +//go:build (linux || darwin) && !appengine +// +build linux darwin +// +build !appengine package util @@ -21,7 +23,7 @@ import ( "syscall" ) -// SysReadFile is a simplified ioutil.ReadFile that invokes syscall.Read directly. +// SysReadFile is a simplified os.ReadFile that invokes syscall.Read directly. // https://github.com/prometheus/node_exporter/pull/728/files // // Note that this function will not read files larger than 128 bytes. @@ -33,7 +35,7 @@ func SysReadFile(file string) (string, error) { defer f.Close() // On some machines, hwmon drivers are broken and return EAGAIN. This causes - // Go's ioutil.ReadFile implementation to poll forever. + // Go's os.ReadFile implementation to poll forever. // // Since we either want to read data or bail immediately, do the simplest // possible read using syscall directly. diff --git a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go index bd55b4537..1d86f5e63 100644 --- a/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go +++ b/vendor/github.com/prometheus/procfs/internal/util/sysreadfile_compat.go @@ -11,7 +11,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux,appengine !linux +//go:build (linux && appengine) || (!linux && !darwin) +// +build linux,appengine !linux,!darwin package util diff --git a/vendor/github.com/prometheus/procfs/ipvs.go b/vendor/github.com/prometheus/procfs/ipvs.go index 89e447746..391c07957 100644 --- a/vendor/github.com/prometheus/procfs/ipvs.go +++ b/vendor/github.com/prometheus/procfs/ipvs.go @@ -20,7 +20,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "os" "strconv" @@ -84,7 +83,7 @@ func parseIPVSStats(r io.Reader) (IPVSStats, error) { stats IPVSStats ) - statContent, err := ioutil.ReadAll(r) + statContent, err := io.ReadAll(r) if err != nil { return IPVSStats{}, err } diff --git a/vendor/github.com/prometheus/procfs/kernel_random.go b/vendor/github.com/prometheus/procfs/kernel_random.go index da3a941d6..db88566bd 100644 --- a/vendor/github.com/prometheus/procfs/kernel_random.go +++ b/vendor/github.com/prometheus/procfs/kernel_random.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs diff --git a/vendor/github.com/prometheus/procfs/loadavg.go b/vendor/github.com/prometheus/procfs/loadavg.go index 0cce190ec..0096cafbd 100644 --- a/vendor/github.com/prometheus/procfs/loadavg.go +++ b/vendor/github.com/prometheus/procfs/loadavg.go @@ -21,7 +21,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// LoadAvg represents an entry in /proc/loadavg +// LoadAvg represents an entry in /proc/loadavg. type LoadAvg struct { Load1 float64 Load5 float64 diff --git a/vendor/github.com/prometheus/procfs/mdstat.go b/vendor/github.com/prometheus/procfs/mdstat.go index f0b9e5f75..a95c889cb 100644 --- a/vendor/github.com/prometheus/procfs/mdstat.go +++ b/vendor/github.com/prometheus/procfs/mdstat.go @@ -15,7 +15,7 @@ package procfs import ( "fmt" - "io/ioutil" + "os" "regexp" "strconv" "strings" @@ -64,7 +64,7 @@ type MDStat struct { // structs containing the relevant info. More information available here: // https://raid.wiki.kernel.org/index.php/Mdstat func (fs FS) MDStat() ([]MDStat, error) { - data, err := ioutil.ReadFile(fs.proc.Path("mdstat")) + data, err := os.ReadFile(fs.proc.Path("mdstat")) if err != nil { return nil, err } @@ -166,8 +166,12 @@ func parseMDStat(mdStatData []byte) ([]MDStat, error) { } func evalStatusLine(deviceLine, statusLine string) (active, total, down, size int64, err error) { + statusFields := strings.Fields(statusLine) + if len(statusFields) < 1 { + return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q", statusLine) + } - sizeStr := strings.Fields(statusLine)[0] + sizeStr := statusFields[0] size, err = strconv.ParseInt(sizeStr, 10, 64) if err != nil { return 0, 0, 0, 0, fmt.Errorf("unexpected statusLine %q: %w", statusLine, err) diff --git a/vendor/github.com/prometheus/procfs/net_conntrackstat.go b/vendor/github.com/prometheus/procfs/net_conntrackstat.go index 9964a3600..8300daca0 100644 --- a/vendor/github.com/prometheus/procfs/net_conntrackstat.go +++ b/vendor/github.com/prometheus/procfs/net_conntrackstat.go @@ -25,7 +25,7 @@ import ( ) // A ConntrackStatEntry represents one line from net/stat/nf_conntrack -// and contains netfilter conntrack statistics at one CPU core +// and contains netfilter conntrack statistics at one CPU core. type ConntrackStatEntry struct { Entries uint64 Found uint64 @@ -38,12 +38,12 @@ type ConntrackStatEntry struct { SearchRestart uint64 } -// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores +// ConntrackStat retrieves netfilter's conntrack statistics, split by CPU cores. func (fs FS) ConntrackStat() ([]ConntrackStatEntry, error) { return readConntrackStat(fs.proc.Path("net", "stat", "nf_conntrack")) } -// Parses a slice of ConntrackStatEntries from the given filepath +// Parses a slice of ConntrackStatEntries from the given filepath. func readConntrackStat(path string) ([]ConntrackStatEntry, error) { // This file is small and can be read with one syscall. b, err := util.ReadFileNoStat(path) @@ -61,7 +61,7 @@ func readConntrackStat(path string) ([]ConntrackStatEntry, error) { return stat, nil } -// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries +// Reads the contents of a conntrack statistics file and parses a slice of ConntrackStatEntries. func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { var entries []ConntrackStatEntry @@ -79,7 +79,7 @@ func parseConntrackStat(r io.Reader) ([]ConntrackStatEntry, error) { return entries, nil } -// Parses a ConntrackStatEntry from given array of fields +// Parses a ConntrackStatEntry from given array of fields. func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { if len(fields) != 17 { return nil, fmt.Errorf("invalid conntrackstat entry, missing fields") @@ -143,7 +143,7 @@ func parseConntrackStatEntry(fields []string) (*ConntrackStatEntry, error) { return entry, nil } -// Parses a uint64 from given hex in string +// Parses a uint64 from given hex in string. func parseConntrackStatField(field string) (uint64, error) { val, err := strconv.ParseUint(field, 16, 64) if err != nil { diff --git a/vendor/github.com/prometheus/procfs/net_dev.go b/vendor/github.com/prometheus/procfs/net_dev.go index 47a710bef..e66208aa0 100644 --- a/vendor/github.com/prometheus/procfs/net_dev.go +++ b/vendor/github.com/prometheus/procfs/net_dev.go @@ -87,17 +87,17 @@ func newNetDev(file string) (NetDev, error) { // parseLine parses a single line from the /proc/net/dev file. Header lines // must be filtered prior to calling this method. func (netDev NetDev) parseLine(rawLine string) (*NetDevLine, error) { - parts := strings.SplitN(rawLine, ":", 2) - if len(parts) != 2 { + idx := strings.LastIndex(rawLine, ":") + if idx == -1 { return nil, errors.New("invalid net/dev line, missing colon") } - fields := strings.Fields(strings.TrimSpace(parts[1])) + fields := strings.Fields(strings.TrimSpace(rawLine[idx+1:])) var err error line := &NetDevLine{} // Interface Name - line.Name = strings.TrimSpace(parts[0]) + line.Name = strings.TrimSpace(rawLine[:idx]) if line.Name == "" { return nil, errors.New("invalid net/dev line, empty interface name") } diff --git a/vendor/github.com/prometheus/procfs/net_ip_socket.go b/vendor/github.com/prometheus/procfs/net_ip_socket.go index 8c9ee3de8..7fd57d7f4 100644 --- a/vendor/github.com/prometheus/procfs/net_ip_socket.go +++ b/vendor/github.com/prometheus/procfs/net_ip_socket.go @@ -34,7 +34,7 @@ const ( readLimit = 4294967296 // Byte -> 4 GiB ) -// this contains generic data structures for both udp and tcp sockets +// This contains generic data structures for both udp and tcp sockets. type ( // NetIPSocket represents the contents of /proc/net/{t,u}dp{,6} file without the header. NetIPSocket []*netIPSocketLine diff --git a/vendor/github.com/prometheus/procfs/net_protocols.go b/vendor/github.com/prometheus/procfs/net_protocols.go index 8c6de3791..374b6f73f 100644 --- a/vendor/github.com/prometheus/procfs/net_protocols.go +++ b/vendor/github.com/prometheus/procfs/net_protocols.go @@ -23,7 +23,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// NetProtocolStats stores the contents from /proc/net/protocols +// NetProtocolStats stores the contents from /proc/net/protocols. type NetProtocolStats map[string]NetProtocolStatLine // NetProtocolStatLine contains a single line parsed from /proc/net/protocols. We @@ -41,7 +41,7 @@ type NetProtocolStatLine struct { Capabilities NetProtocolCapabilities } -// NetProtocolCapabilities contains a list of capabilities for each protocol +// NetProtocolCapabilities contains a list of capabilities for each protocol. type NetProtocolCapabilities struct { Close bool // 8 Connect bool // 9 diff --git a/vendor/github.com/prometheus/procfs/net_softnet.go b/vendor/github.com/prometheus/procfs/net_softnet.go index 46f12c61d..a94f86dc4 100644 --- a/vendor/github.com/prometheus/procfs/net_softnet.go +++ b/vendor/github.com/prometheus/procfs/net_softnet.go @@ -30,13 +30,13 @@ import ( // * Linux 4.17 https://elixir.bootlin.com/linux/v4.17/source/net/core/net-procfs.c#L162 // and https://elixir.bootlin.com/linux/v4.17/source/include/linux/netdevice.h#L2810. -// SoftnetStat contains a single row of data from /proc/net/softnet_stat +// SoftnetStat contains a single row of data from /proc/net/softnet_stat. type SoftnetStat struct { - // Number of processed packets + // Number of processed packets. Processed uint32 - // Number of dropped packets + // Number of dropped packets. Dropped uint32 - // Number of times processing packets ran out of quota + // Number of times processing packets ran out of quota. TimeSqueezed uint32 } diff --git a/vendor/github.com/prometheus/procfs/xfrm.go b/vendor/github.com/prometheus/procfs/net_xfrm.go similarity index 96% rename from vendor/github.com/prometheus/procfs/xfrm.go rename to vendor/github.com/prometheus/procfs/net_xfrm.go index eed07c7d7..f9d9d243d 100644 --- a/vendor/github.com/prometheus/procfs/xfrm.go +++ b/vendor/github.com/prometheus/procfs/net_xfrm.go @@ -79,10 +79,13 @@ type XfrmStat struct { // Policy is dead XfrmOutPolDead int // Policy Error - XfrmOutPolError int - XfrmFwdHdrError int + XfrmOutPolError int + // Forward routing of a packet is not allowed + XfrmFwdHdrError int + // State is invalid, perhaps expired XfrmOutStateInvalid int - XfrmAcquireError int + // State hasn’t been fully acquired before use + XfrmAcquireError int } // NewXfrmStat reads the xfrm_stat statistics. diff --git a/vendor/github.com/prometheus/procfs/netstat.go b/vendor/github.com/prometheus/procfs/netstat.go index 94d892f11..dcea9c5a6 100644 --- a/vendor/github.com/prometheus/procfs/netstat.go +++ b/vendor/github.com/prometheus/procfs/netstat.go @@ -21,13 +21,13 @@ import ( "strings" ) -// NetStat contains statistics for all the counters from one file +// NetStat contains statistics for all the counters from one file. type NetStat struct { - Filename string Stats map[string][]uint64 + Filename string } -// NetStat retrieves stats from /proc/net/stat/ +// NetStat retrieves stats from `/proc/net/stat/`. func (fs FS) NetStat() ([]NetStat, error) { statFiles, err := filepath.Glob(fs.proc.Path("net/stat/*")) if err != nil { @@ -55,7 +55,7 @@ func (fs FS) NetStat() ([]NetStat, error) { // Other strings represent per-CPU counters for scanner.Scan() { for num, counter := range strings.Fields(scanner.Text()) { - value, err := strconv.ParseUint(counter, 16, 32) + value, err := strconv.ParseUint(counter, 16, 64) if err != nil { return nil, err } diff --git a/vendor/github.com/prometheus/procfs/proc.go b/vendor/github.com/prometheus/procfs/proc.go index 28f696803..c30223af7 100644 --- a/vendor/github.com/prometheus/procfs/proc.go +++ b/vendor/github.com/prometheus/procfs/proc.go @@ -16,7 +16,7 @@ package procfs import ( "bytes" "fmt" - "io/ioutil" + "io" "os" "strconv" "strings" @@ -82,7 +82,7 @@ func (fs FS) Self() (Proc, error) { // NewProc returns a process for the given pid. // -// Deprecated: use fs.Proc() instead +// Deprecated: Use fs.Proc() instead. func (fs FS) NewProc(pid int) (Proc, error) { return fs.Proc(pid) } @@ -142,7 +142,7 @@ func (p Proc) Wchan() (string, error) { } defer f.Close() - data, err := ioutil.ReadAll(f) + data, err := io.ReadAll(f) if err != nil { return "", err } @@ -185,7 +185,7 @@ func (p Proc) Cwd() (string, error) { return wd, err } -// RootDir returns the absolute path to the process's root directory (as set by chroot) +// RootDir returns the absolute path to the process's root directory (as set by chroot). func (p Proc) RootDir() (string, error) { rdir, err := os.Readlink(p.path("root")) if os.IsNotExist(err) { @@ -311,7 +311,7 @@ func (p Proc) FileDescriptorsInfo() (ProcFDInfos, error) { // Schedstat returns task scheduling information for the process. func (p Proc) Schedstat() (ProcSchedstat, error) { - contents, err := ioutil.ReadFile(p.path("schedstat")) + contents, err := os.ReadFile(p.path("schedstat")) if err != nil { return ProcSchedstat{}, err } diff --git a/vendor/github.com/prometheus/procfs/proc_cgroup.go b/vendor/github.com/prometheus/procfs/proc_cgroup.go index be45b7987..cca03327c 100644 --- a/vendor/github.com/prometheus/procfs/proc_cgroup.go +++ b/vendor/github.com/prometheus/procfs/proc_cgroup.go @@ -45,7 +45,7 @@ type Cgroup struct { } // parseCgroupString parses each line of the /proc/[pid]/cgroup file -// Line format is hierarchyID:[controller1,controller2]:path +// Line format is hierarchyID:[controller1,controller2]:path. func parseCgroupString(cgroupStr string) (*Cgroup, error) { var err error @@ -69,7 +69,7 @@ func parseCgroupString(cgroupStr string) (*Cgroup, error) { return cgroup, nil } -// parseCgroups reads each line of the /proc/[pid]/cgroup file +// parseCgroups reads each line of the /proc/[pid]/cgroup file. func parseCgroups(data []byte) ([]Cgroup, error) { var cgroups []Cgroup scanner := bufio.NewScanner(bytes.NewReader(data)) @@ -88,7 +88,7 @@ func parseCgroups(data []byte) ([]Cgroup, error) { // Cgroups reads from /proc//cgroups and returns a []*Cgroup struct locating this PID in each process // control hierarchy running on this system. On every system (v1 and v2), all hierarchies contain all processes, -// so the len of the returned struct is equal to the number of active hierarchies on this system +// so the len of the returned struct is equal to the number of active hierarchies on this system. func (p Proc) Cgroups() ([]Cgroup, error) { data, err := util.ReadFileNoStat(p.path("cgroup")) if err != nil { diff --git a/vendor/github.com/prometheus/procfs/proc_cgroups.go b/vendor/github.com/prometheus/procfs/proc_cgroups.go new file mode 100644 index 000000000..24d4dce9c --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_cgroups.go @@ -0,0 +1,98 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "bufio" + "bytes" + "fmt" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// CgroupSummary models one line from /proc/cgroups. +// This file contains information about the controllers that are compiled into the kernel. +// +// Also see http://man7.org/linux/man-pages/man7/cgroups.7.html +type CgroupSummary struct { + // The name of the controller. controller is also known as subsystem. + SubsysName string + // The unique ID of the cgroup hierarchy on which this controller is mounted. + Hierarchy int + // The number of control groups in this hierarchy using this controller. + Cgroups int + // This field contains the value 1 if this controller is enabled, or 0 if it has been disabled + Enabled int +} + +// parseCgroupSummary parses each line of the /proc/cgroup file +// Line format is `subsys_name hierarchy num_cgroups enabled`. +func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) { + var err error + + fields := strings.Fields(CgroupSummaryStr) + // require at least 4 fields + if len(fields) < 4 { + return nil, fmt.Errorf("at least 4 fields required, found %d fields in cgroup info string: %s", len(fields), CgroupSummaryStr) + } + + CgroupSummary := &CgroupSummary{ + SubsysName: fields[0], + } + CgroupSummary.Hierarchy, err = strconv.Atoi(fields[1]) + if err != nil { + return nil, fmt.Errorf("failed to parse hierarchy ID") + } + CgroupSummary.Cgroups, err = strconv.Atoi(fields[2]) + if err != nil { + return nil, fmt.Errorf("failed to parse Cgroup Num") + } + CgroupSummary.Enabled, err = strconv.Atoi(fields[3]) + if err != nil { + return nil, fmt.Errorf("failed to parse Enabled") + } + return CgroupSummary, nil +} + +// parseCgroupSummary reads each line of the /proc/cgroup file. +func parseCgroupSummary(data []byte) ([]CgroupSummary, error) { + var CgroupSummarys []CgroupSummary + scanner := bufio.NewScanner(bytes.NewReader(data)) + for scanner.Scan() { + CgroupSummaryString := scanner.Text() + // ignore comment lines + if strings.HasPrefix(CgroupSummaryString, "#") { + continue + } + CgroupSummary, err := parseCgroupSummaryString(CgroupSummaryString) + if err != nil { + return nil, err + } + CgroupSummarys = append(CgroupSummarys, *CgroupSummary) + } + + err := scanner.Err() + return CgroupSummarys, err +} + +// CgroupSummarys returns information about current /proc/cgroups. +func (fs FS) CgroupSummarys() ([]CgroupSummary, error) { + data, err := util.ReadFileNoStat(fs.proc.Path("cgroups")) + if err != nil { + return nil, err + } + return parseCgroupSummary(data) +} diff --git a/vendor/github.com/prometheus/procfs/proc_environ.go b/vendor/github.com/prometheus/procfs/proc_environ.go index 6134b3580..57a89895d 100644 --- a/vendor/github.com/prometheus/procfs/proc_environ.go +++ b/vendor/github.com/prometheus/procfs/proc_environ.go @@ -19,7 +19,7 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// Environ reads process environments from /proc//environ +// Environ reads process environments from `/proc//environ`. func (p Proc) Environ() ([]string, error) { environments := make([]string, 0) diff --git a/vendor/github.com/prometheus/procfs/proc_fdinfo.go b/vendor/github.com/prometheus/procfs/proc_fdinfo.go index cf63227f0..1bbdd4a8e 100644 --- a/vendor/github.com/prometheus/procfs/proc_fdinfo.go +++ b/vendor/github.com/prometheus/procfs/proc_fdinfo.go @@ -22,7 +22,6 @@ import ( "github.com/prometheus/procfs/internal/util" ) -// Regexp variables var ( rPos = regexp.MustCompile(`^pos:\s+(\d+)$`) rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`) @@ -122,7 +121,7 @@ func (p ProcFDInfos) Len() int { return len(p) } func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD } -// InotifyWatchLen returns the total number of inotify watches +// InotifyWatchLen returns the total number of inotify watches. func (p ProcFDInfos) InotifyWatchLen() (int, error) { length := 0 for _, f := range p { diff --git a/vendor/github.com/prometheus/procfs/proc_limits.go b/vendor/github.com/prometheus/procfs/proc_limits.go index dd20f198a..7a1388185 100644 --- a/vendor/github.com/prometheus/procfs/proc_limits.go +++ b/vendor/github.com/prometheus/procfs/proc_limits.go @@ -79,7 +79,7 @@ var ( // NewLimits returns the current soft limits of the process. // -// Deprecated: use p.Limits() instead +// Deprecated: Use p.Limits() instead. func (p Proc) NewLimits() (ProcLimits, error) { return p.Limits() } diff --git a/vendor/github.com/prometheus/procfs/proc_maps.go b/vendor/github.com/prometheus/procfs/proc_maps.go index 1d7772d51..f1bcbf32b 100644 --- a/vendor/github.com/prometheus/procfs/proc_maps.go +++ b/vendor/github.com/prometheus/procfs/proc_maps.go @@ -11,7 +11,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris) && !js // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris +// +build !js package procfs @@ -25,7 +27,7 @@ import ( "golang.org/x/sys/unix" ) -// ProcMapPermissions contains permission settings read from /proc/[pid]/maps +// ProcMapPermissions contains permission settings read from `/proc/[pid]/maps`. type ProcMapPermissions struct { // mapping has the [R]ead flag set Read bool @@ -39,8 +41,8 @@ type ProcMapPermissions struct { Private bool } -// ProcMap contains the process memory-mappings of the process, -// read from /proc/[pid]/maps +// ProcMap contains the process memory-mappings of the process +// read from `/proc/[pid]/maps`. type ProcMap struct { // The start address of current mapping. StartAddr uintptr @@ -79,7 +81,7 @@ func parseDevice(s string) (uint64, error) { return unix.Mkdev(uint32(major), uint32(minor)), nil } -// parseAddress just converts a hex-string to a uintptr +// parseAddress converts a hex-string to a uintptr. func parseAddress(s string) (uintptr, error) { a, err := strconv.ParseUint(s, 16, 0) if err != nil { @@ -89,7 +91,7 @@ func parseAddress(s string) (uintptr, error) { return uintptr(a), nil } -// parseAddresses parses the start-end address +// parseAddresses parses the start-end address. func parseAddresses(s string) (uintptr, uintptr, error) { toks := strings.Split(s, "-") if len(toks) < 2 { diff --git a/vendor/github.com/prometheus/procfs/proc_netstat.go b/vendor/github.com/prometheus/procfs/proc_netstat.go new file mode 100644 index 000000000..48b523819 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_netstat.go @@ -0,0 +1,440 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// ProcNetstat models the content of /proc//net/netstat. +type ProcNetstat struct { + // The process ID. + PID int + TcpExt + IpExt +} + +type TcpExt struct { // nolint:revive + SyncookiesSent float64 + SyncookiesRecv float64 + SyncookiesFailed float64 + EmbryonicRsts float64 + PruneCalled float64 + RcvPruned float64 + OfoPruned float64 + OutOfWindowIcmps float64 + LockDroppedIcmps float64 + ArpFilter float64 + TW float64 + TWRecycled float64 + TWKilled float64 + PAWSActive float64 + PAWSEstab float64 + DelayedACKs float64 + DelayedACKLocked float64 + DelayedACKLost float64 + ListenOverflows float64 + ListenDrops float64 + TCPHPHits float64 + TCPPureAcks float64 + TCPHPAcks float64 + TCPRenoRecovery float64 + TCPSackRecovery float64 + TCPSACKReneging float64 + TCPSACKReorder float64 + TCPRenoReorder float64 + TCPTSReorder float64 + TCPFullUndo float64 + TCPPartialUndo float64 + TCPDSACKUndo float64 + TCPLossUndo float64 + TCPLostRetransmit float64 + TCPRenoFailures float64 + TCPSackFailures float64 + TCPLossFailures float64 + TCPFastRetrans float64 + TCPSlowStartRetrans float64 + TCPTimeouts float64 + TCPLossProbes float64 + TCPLossProbeRecovery float64 + TCPRenoRecoveryFail float64 + TCPSackRecoveryFail float64 + TCPRcvCollapsed float64 + TCPDSACKOldSent float64 + TCPDSACKOfoSent float64 + TCPDSACKRecv float64 + TCPDSACKOfoRecv float64 + TCPAbortOnData float64 + TCPAbortOnClose float64 + TCPAbortOnMemory float64 + TCPAbortOnTimeout float64 + TCPAbortOnLinger float64 + TCPAbortFailed float64 + TCPMemoryPressures float64 + TCPMemoryPressuresChrono float64 + TCPSACKDiscard float64 + TCPDSACKIgnoredOld float64 + TCPDSACKIgnoredNoUndo float64 + TCPSpuriousRTOs float64 + TCPMD5NotFound float64 + TCPMD5Unexpected float64 + TCPMD5Failure float64 + TCPSackShifted float64 + TCPSackMerged float64 + TCPSackShiftFallback float64 + TCPBacklogDrop float64 + PFMemallocDrop float64 + TCPMinTTLDrop float64 + TCPDeferAcceptDrop float64 + IPReversePathFilter float64 + TCPTimeWaitOverflow float64 + TCPReqQFullDoCookies float64 + TCPReqQFullDrop float64 + TCPRetransFail float64 + TCPRcvCoalesce float64 + TCPOFOQueue float64 + TCPOFODrop float64 + TCPOFOMerge float64 + TCPChallengeACK float64 + TCPSYNChallenge float64 + TCPFastOpenActive float64 + TCPFastOpenActiveFail float64 + TCPFastOpenPassive float64 + TCPFastOpenPassiveFail float64 + TCPFastOpenListenOverflow float64 + TCPFastOpenCookieReqd float64 + TCPFastOpenBlackhole float64 + TCPSpuriousRtxHostQueues float64 + BusyPollRxPackets float64 + TCPAutoCorking float64 + TCPFromZeroWindowAdv float64 + TCPToZeroWindowAdv float64 + TCPWantZeroWindowAdv float64 + TCPSynRetrans float64 + TCPOrigDataSent float64 + TCPHystartTrainDetect float64 + TCPHystartTrainCwnd float64 + TCPHystartDelayDetect float64 + TCPHystartDelayCwnd float64 + TCPACKSkippedSynRecv float64 + TCPACKSkippedPAWS float64 + TCPACKSkippedSeq float64 + TCPACKSkippedFinWait2 float64 + TCPACKSkippedTimeWait float64 + TCPACKSkippedChallenge float64 + TCPWinProbe float64 + TCPKeepAlive float64 + TCPMTUPFail float64 + TCPMTUPSuccess float64 + TCPWqueueTooBig float64 +} + +type IpExt struct { // nolint:revive + InNoRoutes float64 + InTruncatedPkts float64 + InMcastPkts float64 + OutMcastPkts float64 + InBcastPkts float64 + OutBcastPkts float64 + InOctets float64 + OutOctets float64 + InMcastOctets float64 + OutMcastOctets float64 + InBcastOctets float64 + OutBcastOctets float64 + InCsumErrors float64 + InNoECTPkts float64 + InECT1Pkts float64 + InECT0Pkts float64 + InCEPkts float64 + ReasmOverlaps float64 +} + +func (p Proc) Netstat() (ProcNetstat, error) { + filename := p.path("net/netstat") + data, err := util.ReadFileNoStat(filename) + if err != nil { + return ProcNetstat{PID: p.PID}, err + } + procNetstat, err := parseNetstat(bytes.NewReader(data), filename) + procNetstat.PID = p.PID + return procNetstat, err +} + +// parseNetstat parses the metrics from proc//net/netstat file +// and returns a ProcNetstat structure. +func parseNetstat(r io.Reader, fileName string) (ProcNetstat, error) { + var ( + scanner = bufio.NewScanner(r) + procNetstat = ProcNetstat{} + ) + + for scanner.Scan() { + nameParts := strings.Split(scanner.Text(), " ") + scanner.Scan() + valueParts := strings.Split(scanner.Text(), " ") + // Remove trailing :. + protocol := strings.TrimSuffix(nameParts[0], ":") + if len(nameParts) != len(valueParts) { + return procNetstat, fmt.Errorf("mismatch field count mismatch in %s: %s", + fileName, protocol) + } + for i := 1; i < len(nameParts); i++ { + value, err := strconv.ParseFloat(valueParts[i], 64) + if err != nil { + return procNetstat, err + } + key := nameParts[i] + + switch protocol { + case "TcpExt": + switch key { + case "SyncookiesSent": + procNetstat.TcpExt.SyncookiesSent = value + case "SyncookiesRecv": + procNetstat.TcpExt.SyncookiesRecv = value + case "SyncookiesFailed": + procNetstat.TcpExt.SyncookiesFailed = value + case "EmbryonicRsts": + procNetstat.TcpExt.EmbryonicRsts = value + case "PruneCalled": + procNetstat.TcpExt.PruneCalled = value + case "RcvPruned": + procNetstat.TcpExt.RcvPruned = value + case "OfoPruned": + procNetstat.TcpExt.OfoPruned = value + case "OutOfWindowIcmps": + procNetstat.TcpExt.OutOfWindowIcmps = value + case "LockDroppedIcmps": + procNetstat.TcpExt.LockDroppedIcmps = value + case "ArpFilter": + procNetstat.TcpExt.ArpFilter = value + case "TW": + procNetstat.TcpExt.TW = value + case "TWRecycled": + procNetstat.TcpExt.TWRecycled = value + case "TWKilled": + procNetstat.TcpExt.TWKilled = value + case "PAWSActive": + procNetstat.TcpExt.PAWSActive = value + case "PAWSEstab": + procNetstat.TcpExt.PAWSEstab = value + case "DelayedACKs": + procNetstat.TcpExt.DelayedACKs = value + case "DelayedACKLocked": + procNetstat.TcpExt.DelayedACKLocked = value + case "DelayedACKLost": + procNetstat.TcpExt.DelayedACKLost = value + case "ListenOverflows": + procNetstat.TcpExt.ListenOverflows = value + case "ListenDrops": + procNetstat.TcpExt.ListenDrops = value + case "TCPHPHits": + procNetstat.TcpExt.TCPHPHits = value + case "TCPPureAcks": + procNetstat.TcpExt.TCPPureAcks = value + case "TCPHPAcks": + procNetstat.TcpExt.TCPHPAcks = value + case "TCPRenoRecovery": + procNetstat.TcpExt.TCPRenoRecovery = value + case "TCPSackRecovery": + procNetstat.TcpExt.TCPSackRecovery = value + case "TCPSACKReneging": + procNetstat.TcpExt.TCPSACKReneging = value + case "TCPSACKReorder": + procNetstat.TcpExt.TCPSACKReorder = value + case "TCPRenoReorder": + procNetstat.TcpExt.TCPRenoReorder = value + case "TCPTSReorder": + procNetstat.TcpExt.TCPTSReorder = value + case "TCPFullUndo": + procNetstat.TcpExt.TCPFullUndo = value + case "TCPPartialUndo": + procNetstat.TcpExt.TCPPartialUndo = value + case "TCPDSACKUndo": + procNetstat.TcpExt.TCPDSACKUndo = value + case "TCPLossUndo": + procNetstat.TcpExt.TCPLossUndo = value + case "TCPLostRetransmit": + procNetstat.TcpExt.TCPLostRetransmit = value + case "TCPRenoFailures": + procNetstat.TcpExt.TCPRenoFailures = value + case "TCPSackFailures": + procNetstat.TcpExt.TCPSackFailures = value + case "TCPLossFailures": + procNetstat.TcpExt.TCPLossFailures = value + case "TCPFastRetrans": + procNetstat.TcpExt.TCPFastRetrans = value + case "TCPSlowStartRetrans": + procNetstat.TcpExt.TCPSlowStartRetrans = value + case "TCPTimeouts": + procNetstat.TcpExt.TCPTimeouts = value + case "TCPLossProbes": + procNetstat.TcpExt.TCPLossProbes = value + case "TCPLossProbeRecovery": + procNetstat.TcpExt.TCPLossProbeRecovery = value + case "TCPRenoRecoveryFail": + procNetstat.TcpExt.TCPRenoRecoveryFail = value + case "TCPSackRecoveryFail": + procNetstat.TcpExt.TCPSackRecoveryFail = value + case "TCPRcvCollapsed": + procNetstat.TcpExt.TCPRcvCollapsed = value + case "TCPDSACKOldSent": + procNetstat.TcpExt.TCPDSACKOldSent = value + case "TCPDSACKOfoSent": + procNetstat.TcpExt.TCPDSACKOfoSent = value + case "TCPDSACKRecv": + procNetstat.TcpExt.TCPDSACKRecv = value + case "TCPDSACKOfoRecv": + procNetstat.TcpExt.TCPDSACKOfoRecv = value + case "TCPAbortOnData": + procNetstat.TcpExt.TCPAbortOnData = value + case "TCPAbortOnClose": + procNetstat.TcpExt.TCPAbortOnClose = value + case "TCPDeferAcceptDrop": + procNetstat.TcpExt.TCPDeferAcceptDrop = value + case "IPReversePathFilter": + procNetstat.TcpExt.IPReversePathFilter = value + case "TCPTimeWaitOverflow": + procNetstat.TcpExt.TCPTimeWaitOverflow = value + case "TCPReqQFullDoCookies": + procNetstat.TcpExt.TCPReqQFullDoCookies = value + case "TCPReqQFullDrop": + procNetstat.TcpExt.TCPReqQFullDrop = value + case "TCPRetransFail": + procNetstat.TcpExt.TCPRetransFail = value + case "TCPRcvCoalesce": + procNetstat.TcpExt.TCPRcvCoalesce = value + case "TCPOFOQueue": + procNetstat.TcpExt.TCPOFOQueue = value + case "TCPOFODrop": + procNetstat.TcpExt.TCPOFODrop = value + case "TCPOFOMerge": + procNetstat.TcpExt.TCPOFOMerge = value + case "TCPChallengeACK": + procNetstat.TcpExt.TCPChallengeACK = value + case "TCPSYNChallenge": + procNetstat.TcpExt.TCPSYNChallenge = value + case "TCPFastOpenActive": + procNetstat.TcpExt.TCPFastOpenActive = value + case "TCPFastOpenActiveFail": + procNetstat.TcpExt.TCPFastOpenActiveFail = value + case "TCPFastOpenPassive": + procNetstat.TcpExt.TCPFastOpenPassive = value + case "TCPFastOpenPassiveFail": + procNetstat.TcpExt.TCPFastOpenPassiveFail = value + case "TCPFastOpenListenOverflow": + procNetstat.TcpExt.TCPFastOpenListenOverflow = value + case "TCPFastOpenCookieReqd": + procNetstat.TcpExt.TCPFastOpenCookieReqd = value + case "TCPFastOpenBlackhole": + procNetstat.TcpExt.TCPFastOpenBlackhole = value + case "TCPSpuriousRtxHostQueues": + procNetstat.TcpExt.TCPSpuriousRtxHostQueues = value + case "BusyPollRxPackets": + procNetstat.TcpExt.BusyPollRxPackets = value + case "TCPAutoCorking": + procNetstat.TcpExt.TCPAutoCorking = value + case "TCPFromZeroWindowAdv": + procNetstat.TcpExt.TCPFromZeroWindowAdv = value + case "TCPToZeroWindowAdv": + procNetstat.TcpExt.TCPToZeroWindowAdv = value + case "TCPWantZeroWindowAdv": + procNetstat.TcpExt.TCPWantZeroWindowAdv = value + case "TCPSynRetrans": + procNetstat.TcpExt.TCPSynRetrans = value + case "TCPOrigDataSent": + procNetstat.TcpExt.TCPOrigDataSent = value + case "TCPHystartTrainDetect": + procNetstat.TcpExt.TCPHystartTrainDetect = value + case "TCPHystartTrainCwnd": + procNetstat.TcpExt.TCPHystartTrainCwnd = value + case "TCPHystartDelayDetect": + procNetstat.TcpExt.TCPHystartDelayDetect = value + case "TCPHystartDelayCwnd": + procNetstat.TcpExt.TCPHystartDelayCwnd = value + case "TCPACKSkippedSynRecv": + procNetstat.TcpExt.TCPACKSkippedSynRecv = value + case "TCPACKSkippedPAWS": + procNetstat.TcpExt.TCPACKSkippedPAWS = value + case "TCPACKSkippedSeq": + procNetstat.TcpExt.TCPACKSkippedSeq = value + case "TCPACKSkippedFinWait2": + procNetstat.TcpExt.TCPACKSkippedFinWait2 = value + case "TCPACKSkippedTimeWait": + procNetstat.TcpExt.TCPACKSkippedTimeWait = value + case "TCPACKSkippedChallenge": + procNetstat.TcpExt.TCPACKSkippedChallenge = value + case "TCPWinProbe": + procNetstat.TcpExt.TCPWinProbe = value + case "TCPKeepAlive": + procNetstat.TcpExt.TCPKeepAlive = value + case "TCPMTUPFail": + procNetstat.TcpExt.TCPMTUPFail = value + case "TCPMTUPSuccess": + procNetstat.TcpExt.TCPMTUPSuccess = value + case "TCPWqueueTooBig": + procNetstat.TcpExt.TCPWqueueTooBig = value + } + case "IpExt": + switch key { + case "InNoRoutes": + procNetstat.IpExt.InNoRoutes = value + case "InTruncatedPkts": + procNetstat.IpExt.InTruncatedPkts = value + case "InMcastPkts": + procNetstat.IpExt.InMcastPkts = value + case "OutMcastPkts": + procNetstat.IpExt.OutMcastPkts = value + case "InBcastPkts": + procNetstat.IpExt.InBcastPkts = value + case "OutBcastPkts": + procNetstat.IpExt.OutBcastPkts = value + case "InOctets": + procNetstat.IpExt.InOctets = value + case "OutOctets": + procNetstat.IpExt.OutOctets = value + case "InMcastOctets": + procNetstat.IpExt.InMcastOctets = value + case "OutMcastOctets": + procNetstat.IpExt.OutMcastOctets = value + case "InBcastOctets": + procNetstat.IpExt.InBcastOctets = value + case "OutBcastOctets": + procNetstat.IpExt.OutBcastOctets = value + case "InCsumErrors": + procNetstat.IpExt.InCsumErrors = value + case "InNoECTPkts": + procNetstat.IpExt.InNoECTPkts = value + case "InECT1Pkts": + procNetstat.IpExt.InECT1Pkts = value + case "InECT0Pkts": + procNetstat.IpExt.InECT0Pkts = value + case "InCEPkts": + procNetstat.IpExt.InCEPkts = value + case "ReasmOverlaps": + procNetstat.IpExt.ReasmOverlaps = value + } + } + } + } + return procNetstat, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_psi.go b/vendor/github.com/prometheus/procfs/proc_psi.go index dc6c14f0a..a68fe1529 100644 --- a/vendor/github.com/prometheus/procfs/proc_psi.go +++ b/vendor/github.com/prometheus/procfs/proc_psi.go @@ -35,9 +35,10 @@ import ( const lineFormat = "avg10=%f avg60=%f avg300=%f total=%d" -// PSILine is a single line of values as returned by /proc/pressure/* -// The Avg entries are averages over n seconds, as a percentage -// The Total line is in microseconds +// PSILine is a single line of values as returned by `/proc/pressure/*`. +// +// The Avg entries are averages over n seconds, as a percentage. +// The Total line is in microseconds. type PSILine struct { Avg10 float64 Avg60 float64 @@ -46,8 +47,9 @@ type PSILine struct { } // PSIStats represent pressure stall information from /proc/pressure/* -// Some indicates the share of time in which at least some tasks are stalled -// Full indicates the share of time in which all non-idle tasks are stalled simultaneously +// +// "Some" indicates the share of time in which at least some tasks are stalled. +// "Full" indicates the share of time in which all non-idle tasks are stalled simultaneously. type PSIStats struct { Some *PSILine Full *PSILine @@ -65,7 +67,7 @@ func (fs FS) PSIStatsForResource(resource string) (PSIStats, error) { return parsePSIStats(resource, bytes.NewReader(data)) } -// parsePSIStats parses the specified file for pressure stall information +// parsePSIStats parses the specified file for pressure stall information. func parsePSIStats(resource string, r io.Reader) (PSIStats, error) { psiStats := PSIStats{} diff --git a/vendor/github.com/prometheus/procfs/proc_smaps.go b/vendor/github.com/prometheus/procfs/proc_smaps.go index a576a720a..0e97d9957 100644 --- a/vendor/github.com/prometheus/procfs/proc_smaps.go +++ b/vendor/github.com/prometheus/procfs/proc_smaps.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs @@ -28,30 +29,30 @@ import ( ) var ( - // match the header line before each mapped zone in /proc/pid/smaps + // match the header line before each mapped zone in `/proc/pid/smaps`. procSMapsHeaderLine = regexp.MustCompile(`^[a-f0-9].*$`) ) type ProcSMapsRollup struct { - // Amount of the mapping that is currently resident in RAM + // Amount of the mapping that is currently resident in RAM. Rss uint64 - // Process's proportional share of this mapping + // Process's proportional share of this mapping. Pss uint64 - // Size in bytes of clean shared pages + // Size in bytes of clean shared pages. SharedClean uint64 - // Size in bytes of dirty shared pages + // Size in bytes of dirty shared pages. SharedDirty uint64 - // Size in bytes of clean private pages + // Size in bytes of clean private pages. PrivateClean uint64 - // Size in bytes of dirty private pages + // Size in bytes of dirty private pages. PrivateDirty uint64 - // Amount of memory currently marked as referenced or accessed + // Amount of memory currently marked as referenced or accessed. Referenced uint64 - // Amount of memory that does not belong to any file + // Amount of memory that does not belong to any file. Anonymous uint64 - // Amount would-be-anonymous memory currently on swap + // Amount would-be-anonymous memory currently on swap. Swap uint64 - // Process's proportional memory on swap + // Process's proportional memory on swap. SwapPss uint64 } diff --git a/vendor/github.com/prometheus/procfs/proc_snmp.go b/vendor/github.com/prometheus/procfs/proc_snmp.go new file mode 100644 index 000000000..ae191896c --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_snmp.go @@ -0,0 +1,353 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// ProcSnmp models the content of /proc//net/snmp. +type ProcSnmp struct { + // The process ID. + PID int + Ip + Icmp + IcmpMsg + Tcp + Udp + UdpLite +} + +type Ip struct { // nolint:revive + Forwarding float64 + DefaultTTL float64 + InReceives float64 + InHdrErrors float64 + InAddrErrors float64 + ForwDatagrams float64 + InUnknownProtos float64 + InDiscards float64 + InDelivers float64 + OutRequests float64 + OutDiscards float64 + OutNoRoutes float64 + ReasmTimeout float64 + ReasmReqds float64 + ReasmOKs float64 + ReasmFails float64 + FragOKs float64 + FragFails float64 + FragCreates float64 +} + +type Icmp struct { + InMsgs float64 + InErrors float64 + InCsumErrors float64 + InDestUnreachs float64 + InTimeExcds float64 + InParmProbs float64 + InSrcQuenchs float64 + InRedirects float64 + InEchos float64 + InEchoReps float64 + InTimestamps float64 + InTimestampReps float64 + InAddrMasks float64 + InAddrMaskReps float64 + OutMsgs float64 + OutErrors float64 + OutDestUnreachs float64 + OutTimeExcds float64 + OutParmProbs float64 + OutSrcQuenchs float64 + OutRedirects float64 + OutEchos float64 + OutEchoReps float64 + OutTimestamps float64 + OutTimestampReps float64 + OutAddrMasks float64 + OutAddrMaskReps float64 +} + +type IcmpMsg struct { + InType3 float64 + OutType3 float64 +} + +type Tcp struct { // nolint:revive + RtoAlgorithm float64 + RtoMin float64 + RtoMax float64 + MaxConn float64 + ActiveOpens float64 + PassiveOpens float64 + AttemptFails float64 + EstabResets float64 + CurrEstab float64 + InSegs float64 + OutSegs float64 + RetransSegs float64 + InErrs float64 + OutRsts float64 + InCsumErrors float64 +} + +type Udp struct { // nolint:revive + InDatagrams float64 + NoPorts float64 + InErrors float64 + OutDatagrams float64 + RcvbufErrors float64 + SndbufErrors float64 + InCsumErrors float64 + IgnoredMulti float64 +} + +type UdpLite struct { // nolint:revive + InDatagrams float64 + NoPorts float64 + InErrors float64 + OutDatagrams float64 + RcvbufErrors float64 + SndbufErrors float64 + InCsumErrors float64 + IgnoredMulti float64 +} + +func (p Proc) Snmp() (ProcSnmp, error) { + filename := p.path("net/snmp") + data, err := util.ReadFileNoStat(filename) + if err != nil { + return ProcSnmp{PID: p.PID}, err + } + procSnmp, err := parseSnmp(bytes.NewReader(data), filename) + procSnmp.PID = p.PID + return procSnmp, err +} + +// parseSnmp parses the metrics from proc//net/snmp file +// and returns a map contains those metrics (e.g. {"Ip": {"Forwarding": 2}}). +func parseSnmp(r io.Reader, fileName string) (ProcSnmp, error) { + var ( + scanner = bufio.NewScanner(r) + procSnmp = ProcSnmp{} + ) + + for scanner.Scan() { + nameParts := strings.Split(scanner.Text(), " ") + scanner.Scan() + valueParts := strings.Split(scanner.Text(), " ") + // Remove trailing :. + protocol := strings.TrimSuffix(nameParts[0], ":") + if len(nameParts) != len(valueParts) { + return procSnmp, fmt.Errorf("mismatch field count mismatch in %s: %s", + fileName, protocol) + } + for i := 1; i < len(nameParts); i++ { + value, err := strconv.ParseFloat(valueParts[i], 64) + if err != nil { + return procSnmp, err + } + key := nameParts[i] + + switch protocol { + case "Ip": + switch key { + case "Forwarding": + procSnmp.Ip.Forwarding = value + case "DefaultTTL": + procSnmp.Ip.DefaultTTL = value + case "InReceives": + procSnmp.Ip.InReceives = value + case "InHdrErrors": + procSnmp.Ip.InHdrErrors = value + case "InAddrErrors": + procSnmp.Ip.InAddrErrors = value + case "ForwDatagrams": + procSnmp.Ip.ForwDatagrams = value + case "InUnknownProtos": + procSnmp.Ip.InUnknownProtos = value + case "InDiscards": + procSnmp.Ip.InDiscards = value + case "InDelivers": + procSnmp.Ip.InDelivers = value + case "OutRequests": + procSnmp.Ip.OutRequests = value + case "OutDiscards": + procSnmp.Ip.OutDiscards = value + case "OutNoRoutes": + procSnmp.Ip.OutNoRoutes = value + case "ReasmTimeout": + procSnmp.Ip.ReasmTimeout = value + case "ReasmReqds": + procSnmp.Ip.ReasmReqds = value + case "ReasmOKs": + procSnmp.Ip.ReasmOKs = value + case "ReasmFails": + procSnmp.Ip.ReasmFails = value + case "FragOKs": + procSnmp.Ip.FragOKs = value + case "FragFails": + procSnmp.Ip.FragFails = value + case "FragCreates": + procSnmp.Ip.FragCreates = value + } + case "Icmp": + switch key { + case "InMsgs": + procSnmp.Icmp.InMsgs = value + case "InErrors": + procSnmp.Icmp.InErrors = value + case "InCsumErrors": + procSnmp.Icmp.InCsumErrors = value + case "InDestUnreachs": + procSnmp.Icmp.InDestUnreachs = value + case "InTimeExcds": + procSnmp.Icmp.InTimeExcds = value + case "InParmProbs": + procSnmp.Icmp.InParmProbs = value + case "InSrcQuenchs": + procSnmp.Icmp.InSrcQuenchs = value + case "InRedirects": + procSnmp.Icmp.InRedirects = value + case "InEchos": + procSnmp.Icmp.InEchos = value + case "InEchoReps": + procSnmp.Icmp.InEchoReps = value + case "InTimestamps": + procSnmp.Icmp.InTimestamps = value + case "InTimestampReps": + procSnmp.Icmp.InTimestampReps = value + case "InAddrMasks": + procSnmp.Icmp.InAddrMasks = value + case "InAddrMaskReps": + procSnmp.Icmp.InAddrMaskReps = value + case "OutMsgs": + procSnmp.Icmp.OutMsgs = value + case "OutErrors": + procSnmp.Icmp.OutErrors = value + case "OutDestUnreachs": + procSnmp.Icmp.OutDestUnreachs = value + case "OutTimeExcds": + procSnmp.Icmp.OutTimeExcds = value + case "OutParmProbs": + procSnmp.Icmp.OutParmProbs = value + case "OutSrcQuenchs": + procSnmp.Icmp.OutSrcQuenchs = value + case "OutRedirects": + procSnmp.Icmp.OutRedirects = value + case "OutEchos": + procSnmp.Icmp.OutEchos = value + case "OutEchoReps": + procSnmp.Icmp.OutEchoReps = value + case "OutTimestamps": + procSnmp.Icmp.OutTimestamps = value + case "OutTimestampReps": + procSnmp.Icmp.OutTimestampReps = value + case "OutAddrMasks": + procSnmp.Icmp.OutAddrMasks = value + case "OutAddrMaskReps": + procSnmp.Icmp.OutAddrMaskReps = value + } + case "IcmpMsg": + switch key { + case "InType3": + procSnmp.IcmpMsg.InType3 = value + case "OutType3": + procSnmp.IcmpMsg.OutType3 = value + } + case "Tcp": + switch key { + case "RtoAlgorithm": + procSnmp.Tcp.RtoAlgorithm = value + case "RtoMin": + procSnmp.Tcp.RtoMin = value + case "RtoMax": + procSnmp.Tcp.RtoMax = value + case "MaxConn": + procSnmp.Tcp.MaxConn = value + case "ActiveOpens": + procSnmp.Tcp.ActiveOpens = value + case "PassiveOpens": + procSnmp.Tcp.PassiveOpens = value + case "AttemptFails": + procSnmp.Tcp.AttemptFails = value + case "EstabResets": + procSnmp.Tcp.EstabResets = value + case "CurrEstab": + procSnmp.Tcp.CurrEstab = value + case "InSegs": + procSnmp.Tcp.InSegs = value + case "OutSegs": + procSnmp.Tcp.OutSegs = value + case "RetransSegs": + procSnmp.Tcp.RetransSegs = value + case "InErrs": + procSnmp.Tcp.InErrs = value + case "OutRsts": + procSnmp.Tcp.OutRsts = value + case "InCsumErrors": + procSnmp.Tcp.InCsumErrors = value + } + case "Udp": + switch key { + case "InDatagrams": + procSnmp.Udp.InDatagrams = value + case "NoPorts": + procSnmp.Udp.NoPorts = value + case "InErrors": + procSnmp.Udp.InErrors = value + case "OutDatagrams": + procSnmp.Udp.OutDatagrams = value + case "RcvbufErrors": + procSnmp.Udp.RcvbufErrors = value + case "SndbufErrors": + procSnmp.Udp.SndbufErrors = value + case "InCsumErrors": + procSnmp.Udp.InCsumErrors = value + case "IgnoredMulti": + procSnmp.Udp.IgnoredMulti = value + } + case "UdpLite": + switch key { + case "InDatagrams": + procSnmp.UdpLite.InDatagrams = value + case "NoPorts": + procSnmp.UdpLite.NoPorts = value + case "InErrors": + procSnmp.UdpLite.InErrors = value + case "OutDatagrams": + procSnmp.UdpLite.OutDatagrams = value + case "RcvbufErrors": + procSnmp.UdpLite.RcvbufErrors = value + case "SndbufErrors": + procSnmp.UdpLite.SndbufErrors = value + case "InCsumErrors": + procSnmp.UdpLite.InCsumErrors = value + case "IgnoredMulti": + procSnmp.UdpLite.IgnoredMulti = value + } + } + } + } + return procSnmp, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_snmp6.go b/vendor/github.com/prometheus/procfs/proc_snmp6.go new file mode 100644 index 000000000..f611992d5 --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_snmp6.go @@ -0,0 +1,381 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "bufio" + "bytes" + "errors" + "io" + "os" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// ProcSnmp6 models the content of /proc//net/snmp6. +type ProcSnmp6 struct { + // The process ID. + PID int + Ip6 + Icmp6 + Udp6 + UdpLite6 +} + +type Ip6 struct { // nolint:revive + InReceives float64 + InHdrErrors float64 + InTooBigErrors float64 + InNoRoutes float64 + InAddrErrors float64 + InUnknownProtos float64 + InTruncatedPkts float64 + InDiscards float64 + InDelivers float64 + OutForwDatagrams float64 + OutRequests float64 + OutDiscards float64 + OutNoRoutes float64 + ReasmTimeout float64 + ReasmReqds float64 + ReasmOKs float64 + ReasmFails float64 + FragOKs float64 + FragFails float64 + FragCreates float64 + InMcastPkts float64 + OutMcastPkts float64 + InOctets float64 + OutOctets float64 + InMcastOctets float64 + OutMcastOctets float64 + InBcastOctets float64 + OutBcastOctets float64 + InNoECTPkts float64 + InECT1Pkts float64 + InECT0Pkts float64 + InCEPkts float64 +} + +type Icmp6 struct { + InMsgs float64 + InErrors float64 + OutMsgs float64 + OutErrors float64 + InCsumErrors float64 + InDestUnreachs float64 + InPktTooBigs float64 + InTimeExcds float64 + InParmProblems float64 + InEchos float64 + InEchoReplies float64 + InGroupMembQueries float64 + InGroupMembResponses float64 + InGroupMembReductions float64 + InRouterSolicits float64 + InRouterAdvertisements float64 + InNeighborSolicits float64 + InNeighborAdvertisements float64 + InRedirects float64 + InMLDv2Reports float64 + OutDestUnreachs float64 + OutPktTooBigs float64 + OutTimeExcds float64 + OutParmProblems float64 + OutEchos float64 + OutEchoReplies float64 + OutGroupMembQueries float64 + OutGroupMembResponses float64 + OutGroupMembReductions float64 + OutRouterSolicits float64 + OutRouterAdvertisements float64 + OutNeighborSolicits float64 + OutNeighborAdvertisements float64 + OutRedirects float64 + OutMLDv2Reports float64 + InType1 float64 + InType134 float64 + InType135 float64 + InType136 float64 + InType143 float64 + OutType133 float64 + OutType135 float64 + OutType136 float64 + OutType143 float64 +} + +type Udp6 struct { // nolint:revive + InDatagrams float64 + NoPorts float64 + InErrors float64 + OutDatagrams float64 + RcvbufErrors float64 + SndbufErrors float64 + InCsumErrors float64 + IgnoredMulti float64 +} + +type UdpLite6 struct { // nolint:revive + InDatagrams float64 + NoPorts float64 + InErrors float64 + OutDatagrams float64 + RcvbufErrors float64 + SndbufErrors float64 + InCsumErrors float64 +} + +func (p Proc) Snmp6() (ProcSnmp6, error) { + filename := p.path("net/snmp6") + data, err := util.ReadFileNoStat(filename) + if err != nil { + // On systems with IPv6 disabled, this file won't exist. + // Do nothing. + if errors.Is(err, os.ErrNotExist) { + return ProcSnmp6{PID: p.PID}, nil + } + + return ProcSnmp6{PID: p.PID}, err + } + + procSnmp6, err := parseSNMP6Stats(bytes.NewReader(data)) + procSnmp6.PID = p.PID + return procSnmp6, err +} + +// parseSnmp6 parses the metrics from proc//net/snmp6 file +// and returns a map contains those metrics. +func parseSNMP6Stats(r io.Reader) (ProcSnmp6, error) { + var ( + scanner = bufio.NewScanner(r) + procSnmp6 = ProcSnmp6{} + ) + + for scanner.Scan() { + stat := strings.Fields(scanner.Text()) + if len(stat) < 2 { + continue + } + // Expect to have "6" in metric name, skip line otherwise + if sixIndex := strings.Index(stat[0], "6"); sixIndex != -1 { + protocol := stat[0][:sixIndex+1] + key := stat[0][sixIndex+1:] + value, err := strconv.ParseFloat(stat[1], 64) + if err != nil { + return procSnmp6, err + } + + switch protocol { + case "Ip6": + switch key { + case "InReceives": + procSnmp6.Ip6.InReceives = value + case "InHdrErrors": + procSnmp6.Ip6.InHdrErrors = value + case "InTooBigErrors": + procSnmp6.Ip6.InTooBigErrors = value + case "InNoRoutes": + procSnmp6.Ip6.InNoRoutes = value + case "InAddrErrors": + procSnmp6.Ip6.InAddrErrors = value + case "InUnknownProtos": + procSnmp6.Ip6.InUnknownProtos = value + case "InTruncatedPkts": + procSnmp6.Ip6.InTruncatedPkts = value + case "InDiscards": + procSnmp6.Ip6.InDiscards = value + case "InDelivers": + procSnmp6.Ip6.InDelivers = value + case "OutForwDatagrams": + procSnmp6.Ip6.OutForwDatagrams = value + case "OutRequests": + procSnmp6.Ip6.OutRequests = value + case "OutDiscards": + procSnmp6.Ip6.OutDiscards = value + case "OutNoRoutes": + procSnmp6.Ip6.OutNoRoutes = value + case "ReasmTimeout": + procSnmp6.Ip6.ReasmTimeout = value + case "ReasmReqds": + procSnmp6.Ip6.ReasmReqds = value + case "ReasmOKs": + procSnmp6.Ip6.ReasmOKs = value + case "ReasmFails": + procSnmp6.Ip6.ReasmFails = value + case "FragOKs": + procSnmp6.Ip6.FragOKs = value + case "FragFails": + procSnmp6.Ip6.FragFails = value + case "FragCreates": + procSnmp6.Ip6.FragCreates = value + case "InMcastPkts": + procSnmp6.Ip6.InMcastPkts = value + case "OutMcastPkts": + procSnmp6.Ip6.OutMcastPkts = value + case "InOctets": + procSnmp6.Ip6.InOctets = value + case "OutOctets": + procSnmp6.Ip6.OutOctets = value + case "InMcastOctets": + procSnmp6.Ip6.InMcastOctets = value + case "OutMcastOctets": + procSnmp6.Ip6.OutMcastOctets = value + case "InBcastOctets": + procSnmp6.Ip6.InBcastOctets = value + case "OutBcastOctets": + procSnmp6.Ip6.OutBcastOctets = value + case "InNoECTPkts": + procSnmp6.Ip6.InNoECTPkts = value + case "InECT1Pkts": + procSnmp6.Ip6.InECT1Pkts = value + case "InECT0Pkts": + procSnmp6.Ip6.InECT0Pkts = value + case "InCEPkts": + procSnmp6.Ip6.InCEPkts = value + + } + case "Icmp6": + switch key { + case "InMsgs": + procSnmp6.Icmp6.InMsgs = value + case "InErrors": + procSnmp6.Icmp6.InErrors = value + case "OutMsgs": + procSnmp6.Icmp6.OutMsgs = value + case "OutErrors": + procSnmp6.Icmp6.OutErrors = value + case "InCsumErrors": + procSnmp6.Icmp6.InCsumErrors = value + case "InDestUnreachs": + procSnmp6.Icmp6.InDestUnreachs = value + case "InPktTooBigs": + procSnmp6.Icmp6.InPktTooBigs = value + case "InTimeExcds": + procSnmp6.Icmp6.InTimeExcds = value + case "InParmProblems": + procSnmp6.Icmp6.InParmProblems = value + case "InEchos": + procSnmp6.Icmp6.InEchos = value + case "InEchoReplies": + procSnmp6.Icmp6.InEchoReplies = value + case "InGroupMembQueries": + procSnmp6.Icmp6.InGroupMembQueries = value + case "InGroupMembResponses": + procSnmp6.Icmp6.InGroupMembResponses = value + case "InGroupMembReductions": + procSnmp6.Icmp6.InGroupMembReductions = value + case "InRouterSolicits": + procSnmp6.Icmp6.InRouterSolicits = value + case "InRouterAdvertisements": + procSnmp6.Icmp6.InRouterAdvertisements = value + case "InNeighborSolicits": + procSnmp6.Icmp6.InNeighborSolicits = value + case "InNeighborAdvertisements": + procSnmp6.Icmp6.InNeighborAdvertisements = value + case "InRedirects": + procSnmp6.Icmp6.InRedirects = value + case "InMLDv2Reports": + procSnmp6.Icmp6.InMLDv2Reports = value + case "OutDestUnreachs": + procSnmp6.Icmp6.OutDestUnreachs = value + case "OutPktTooBigs": + procSnmp6.Icmp6.OutPktTooBigs = value + case "OutTimeExcds": + procSnmp6.Icmp6.OutTimeExcds = value + case "OutParmProblems": + procSnmp6.Icmp6.OutParmProblems = value + case "OutEchos": + procSnmp6.Icmp6.OutEchos = value + case "OutEchoReplies": + procSnmp6.Icmp6.OutEchoReplies = value + case "OutGroupMembQueries": + procSnmp6.Icmp6.OutGroupMembQueries = value + case "OutGroupMembResponses": + procSnmp6.Icmp6.OutGroupMembResponses = value + case "OutGroupMembReductions": + procSnmp6.Icmp6.OutGroupMembReductions = value + case "OutRouterSolicits": + procSnmp6.Icmp6.OutRouterSolicits = value + case "OutRouterAdvertisements": + procSnmp6.Icmp6.OutRouterAdvertisements = value + case "OutNeighborSolicits": + procSnmp6.Icmp6.OutNeighborSolicits = value + case "OutNeighborAdvertisements": + procSnmp6.Icmp6.OutNeighborAdvertisements = value + case "OutRedirects": + procSnmp6.Icmp6.OutRedirects = value + case "OutMLDv2Reports": + procSnmp6.Icmp6.OutMLDv2Reports = value + case "InType1": + procSnmp6.Icmp6.InType1 = value + case "InType134": + procSnmp6.Icmp6.InType134 = value + case "InType135": + procSnmp6.Icmp6.InType135 = value + case "InType136": + procSnmp6.Icmp6.InType136 = value + case "InType143": + procSnmp6.Icmp6.InType143 = value + case "OutType133": + procSnmp6.Icmp6.OutType133 = value + case "OutType135": + procSnmp6.Icmp6.OutType135 = value + case "OutType136": + procSnmp6.Icmp6.OutType136 = value + case "OutType143": + procSnmp6.Icmp6.OutType143 = value + } + case "Udp6": + switch key { + case "InDatagrams": + procSnmp6.Udp6.InDatagrams = value + case "NoPorts": + procSnmp6.Udp6.NoPorts = value + case "InErrors": + procSnmp6.Udp6.InErrors = value + case "OutDatagrams": + procSnmp6.Udp6.OutDatagrams = value + case "RcvbufErrors": + procSnmp6.Udp6.RcvbufErrors = value + case "SndbufErrors": + procSnmp6.Udp6.SndbufErrors = value + case "InCsumErrors": + procSnmp6.Udp6.InCsumErrors = value + case "IgnoredMulti": + procSnmp6.Udp6.IgnoredMulti = value + } + case "UdpLite6": + switch key { + case "InDatagrams": + procSnmp6.UdpLite6.InDatagrams = value + case "NoPorts": + procSnmp6.UdpLite6.NoPorts = value + case "InErrors": + procSnmp6.UdpLite6.InErrors = value + case "OutDatagrams": + procSnmp6.UdpLite6.OutDatagrams = value + case "RcvbufErrors": + procSnmp6.UdpLite6.RcvbufErrors = value + case "SndbufErrors": + procSnmp6.UdpLite6.SndbufErrors = value + case "InCsumErrors": + procSnmp6.UdpLite6.InCsumErrors = value + } + } + } + } + return procSnmp6, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/proc_stat.go b/vendor/github.com/prometheus/procfs/proc_stat.go index 8c7b6e80a..06c556ef9 100644 --- a/vendor/github.com/prometheus/procfs/proc_stat.go +++ b/vendor/github.com/prometheus/procfs/proc_stat.go @@ -81,10 +81,10 @@ type ProcStat struct { STime uint // Amount of time that this process's waited-for children have been // scheduled in user mode, measured in clock ticks. - CUTime uint + CUTime int // Amount of time that this process's waited-for children have been // scheduled in kernel mode, measured in clock ticks. - CSTime uint + CSTime int // For processes running a real-time scheduling policy, this is the negated // scheduling priority, minus one. Priority int @@ -115,7 +115,7 @@ type ProcStat struct { // NewStat returns the current status information of the process. // -// Deprecated: use p.Stat() instead +// Deprecated: Use p.Stat() instead. func (p Proc) NewStat() (ProcStat, error) { return p.Stat() } @@ -141,6 +141,11 @@ func (p Proc) Stat() (ProcStat, error) { } s.Comm = string(data[l+1 : r]) + + // Check the following resources for the details about the particular stat + // fields and their data types: + // * https://man7.org/linux/man-pages/man5/proc.5.html + // * https://man7.org/linux/man-pages/man3/scanf.3.html _, err = fmt.Fscan( bytes.NewBuffer(data[r+2:]), &s.State, diff --git a/vendor/github.com/prometheus/procfs/proc_status.go b/vendor/github.com/prometheus/procfs/proc_status.go index 6edd8333b..594022ded 100644 --- a/vendor/github.com/prometheus/procfs/proc_status.go +++ b/vendor/github.com/prometheus/procfs/proc_status.go @@ -33,37 +33,37 @@ type ProcStatus struct { TGID int // Peak virtual memory size. - VmPeak uint64 // nolint:golint + VmPeak uint64 // nolint:revive // Virtual memory size. - VmSize uint64 // nolint:golint + VmSize uint64 // nolint:revive // Locked memory size. - VmLck uint64 // nolint:golint + VmLck uint64 // nolint:revive // Pinned memory size. - VmPin uint64 // nolint:golint + VmPin uint64 // nolint:revive // Peak resident set size. - VmHWM uint64 // nolint:golint + VmHWM uint64 // nolint:revive // Resident set size (sum of RssAnnon RssFile and RssShmem). - VmRSS uint64 // nolint:golint + VmRSS uint64 // nolint:revive // Size of resident anonymous memory. - RssAnon uint64 // nolint:golint + RssAnon uint64 // nolint:revive // Size of resident file mappings. - RssFile uint64 // nolint:golint + RssFile uint64 // nolint:revive // Size of resident shared memory. - RssShmem uint64 // nolint:golint + RssShmem uint64 // nolint:revive // Size of data segments. - VmData uint64 // nolint:golint + VmData uint64 // nolint:revive // Size of stack segments. - VmStk uint64 // nolint:golint + VmStk uint64 // nolint:revive // Size of text segments. - VmExe uint64 // nolint:golint + VmExe uint64 // nolint:revive // Shared library code size. - VmLib uint64 // nolint:golint + VmLib uint64 // nolint:revive // Page table entries size. - VmPTE uint64 // nolint:golint + VmPTE uint64 // nolint:revive // Size of second-level page tables. - VmPMD uint64 // nolint:golint + VmPMD uint64 // nolint:revive // Swapped-out virtual memory size by anonymous private. - VmSwap uint64 // nolint:golint + VmSwap uint64 // nolint:revive // Size of hugetlb memory portions HugetlbPages uint64 diff --git a/vendor/github.com/prometheus/procfs/proc_sys.go b/vendor/github.com/prometheus/procfs/proc_sys.go new file mode 100644 index 000000000..d46533ebf --- /dev/null +++ b/vendor/github.com/prometheus/procfs/proc_sys.go @@ -0,0 +1,51 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "fmt" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +func sysctlToPath(sysctl string) string { + return strings.Replace(sysctl, ".", "/", -1) +} + +func (fs FS) SysctlStrings(sysctl string) ([]string, error) { + value, err := util.SysReadFile(fs.proc.Path("sys", sysctlToPath(sysctl))) + if err != nil { + return nil, err + } + return strings.Fields(value), nil + +} + +func (fs FS) SysctlInts(sysctl string) ([]int, error) { + fields, err := fs.SysctlStrings(sysctl) + if err != nil { + return nil, err + } + + values := make([]int, len(fields)) + for i, f := range fields { + vp := util.NewValueParser(f) + values[i] = vp.Int() + if err := vp.Err(); err != nil { + return nil, fmt.Errorf("field %d in sysctl %s is not a valid int: %w", i, sysctl, err) + } + } + return values, nil +} diff --git a/vendor/github.com/prometheus/procfs/schedstat.go b/vendor/github.com/prometheus/procfs/schedstat.go index 28228164e..5f7f32dc8 100644 --- a/vendor/github.com/prometheus/procfs/schedstat.go +++ b/vendor/github.com/prometheus/procfs/schedstat.go @@ -40,7 +40,7 @@ type Schedstat struct { CPUs []*SchedstatCPU } -// SchedstatCPU contains the values from one "cpu" line +// SchedstatCPU contains the values from one "cpu" line. type SchedstatCPU struct { CPUNum string @@ -49,14 +49,14 @@ type SchedstatCPU struct { RunTimeslices uint64 } -// ProcSchedstat contains the values from /proc//schedstat +// ProcSchedstat contains the values from `/proc//schedstat`. type ProcSchedstat struct { RunningNanoseconds uint64 WaitingNanoseconds uint64 RunTimeslices uint64 } -// Schedstat reads data from /proc/schedstat +// Schedstat reads data from `/proc/schedstat`. func (fs FS) Schedstat() (*Schedstat, error) { file, err := os.Open(fs.proc.Path("schedstat")) if err != nil { diff --git a/vendor/github.com/prometheus/procfs/slab.go b/vendor/github.com/prometheus/procfs/slab.go index 7896fd724..bc9aaf5c2 100644 --- a/vendor/github.com/prometheus/procfs/slab.go +++ b/vendor/github.com/prometheus/procfs/slab.go @@ -137,7 +137,7 @@ func parseSlabInfo21(r *bytes.Reader) (SlabInfo, error) { return s, nil } -// SlabInfo reads data from /proc/slabinfo +// SlabInfo reads data from `/proc/slabinfo`. func (fs FS) SlabInfo() (SlabInfo, error) { // TODO: Consider passing options to allow for parsing different // slabinfo versions. However, slabinfo 2.1 has been stable since diff --git a/vendor/github.com/prometheus/procfs/softirqs.go b/vendor/github.com/prometheus/procfs/softirqs.go new file mode 100644 index 000000000..559129cbc --- /dev/null +++ b/vendor/github.com/prometheus/procfs/softirqs.go @@ -0,0 +1,160 @@ +// Copyright 2022 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package procfs + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strconv" + "strings" + + "github.com/prometheus/procfs/internal/util" +) + +// Softirqs represents the softirq statistics. +type Softirqs struct { + Hi []uint64 + Timer []uint64 + NetTx []uint64 + NetRx []uint64 + Block []uint64 + IRQPoll []uint64 + Tasklet []uint64 + Sched []uint64 + HRTimer []uint64 + RCU []uint64 +} + +func (fs FS) Softirqs() (Softirqs, error) { + fileName := fs.proc.Path("softirqs") + data, err := util.ReadFileNoStat(fileName) + if err != nil { + return Softirqs{}, err + } + + reader := bytes.NewReader(data) + + return parseSoftirqs(reader) +} + +func parseSoftirqs(r io.Reader) (Softirqs, error) { + var ( + softirqs = Softirqs{} + scanner = bufio.NewScanner(r) + ) + + if !scanner.Scan() { + return Softirqs{}, fmt.Errorf("softirqs empty") + } + + for scanner.Scan() { + parts := strings.Fields(scanner.Text()) + var err error + + // require at least one cpu + if len(parts) < 2 { + continue + } + switch { + case parts[0] == "HI:": + perCPU := parts[1:] + softirqs.Hi = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Hi[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (HI%d): %w", count, i, err) + } + } + case parts[0] == "TIMER:": + perCPU := parts[1:] + softirqs.Timer = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Timer[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (TIMER%d): %w", count, i, err) + } + } + case parts[0] == "NET_TX:": + perCPU := parts[1:] + softirqs.NetTx = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.NetTx[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_TX%d): %w", count, i, err) + } + } + case parts[0] == "NET_RX:": + perCPU := parts[1:] + softirqs.NetRx = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.NetRx[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (NET_RX%d): %w", count, i, err) + } + } + case parts[0] == "BLOCK:": + perCPU := parts[1:] + softirqs.Block = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Block[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (BLOCK%d): %w", count, i, err) + } + } + case parts[0] == "IRQ_POLL:": + perCPU := parts[1:] + softirqs.IRQPoll = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.IRQPoll[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (IRQ_POLL%d): %w", count, i, err) + } + } + case parts[0] == "TASKLET:": + perCPU := parts[1:] + softirqs.Tasklet = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Tasklet[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (TASKLET%d): %w", count, i, err) + } + } + case parts[0] == "SCHED:": + perCPU := parts[1:] + softirqs.Sched = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.Sched[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (SCHED%d): %w", count, i, err) + } + } + case parts[0] == "HRTIMER:": + perCPU := parts[1:] + softirqs.HRTimer = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.HRTimer[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (HRTIMER%d): %w", count, i, err) + } + } + case parts[0] == "RCU:": + perCPU := parts[1:] + softirqs.RCU = make([]uint64, len(perCPU)) + for i, count := range perCPU { + if softirqs.RCU[i], err = strconv.ParseUint(count, 10, 64); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse %q (RCU%d): %w", count, i, err) + } + } + } + } + + if err := scanner.Err(); err != nil { + return Softirqs{}, fmt.Errorf("couldn't parse softirqs: %w", err) + } + + return softirqs, scanner.Err() +} diff --git a/vendor/github.com/prometheus/procfs/stat.go b/vendor/github.com/prometheus/procfs/stat.go index 6d8727541..33f97caa0 100644 --- a/vendor/github.com/prometheus/procfs/stat.go +++ b/vendor/github.com/prometheus/procfs/stat.go @@ -41,7 +41,7 @@ type CPUStat struct { // SoftIRQStat represent the softirq statistics as exported in the procfs stat file. // A nice introduction can be found at https://0xax.gitbooks.io/linux-insides/content/interrupts/interrupts-9.html -// It is possible to get per-cpu stats by reading /proc/softirqs +// It is possible to get per-cpu stats by reading `/proc/softirqs`. type SoftIRQStat struct { Hi uint64 Timer uint64 @@ -145,7 +145,7 @@ func parseSoftIRQStat(line string) (SoftIRQStat, uint64, error) { // NewStat returns information about current cpu/process statistics. // See https://www.kernel.org/doc/Documentation/filesystems/proc.txt // -// Deprecated: use fs.Stat() instead +// Deprecated: Use fs.Stat() instead. func NewStat() (Stat, error) { fs, err := NewFS(fs.DefaultProcMountPoint) if err != nil { @@ -155,15 +155,15 @@ func NewStat() (Stat, error) { } // NewStat returns information about current cpu/process statistics. -// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt +// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt // -// Deprecated: use fs.Stat() instead +// Deprecated: Use fs.Stat() instead. func (fs FS) NewStat() (Stat, error) { return fs.Stat() } // Stat returns information about current cpu/process statistics. -// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt +// See: https://www.kernel.org/doc/Documentation/filesystems/proc.txt func (fs FS) Stat() (Stat, error) { fileName := fs.proc.Path("stat") data, err := util.ReadFileNoStat(fileName) diff --git a/vendor/github.com/prometheus/procfs/vm.go b/vendor/github.com/prometheus/procfs/vm.go index cb1389141..20ceb77e2 100644 --- a/vendor/github.com/prometheus/procfs/vm.go +++ b/vendor/github.com/prometheus/procfs/vm.go @@ -11,13 +11,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs import ( "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -29,7 +29,7 @@ import ( // https://www.kernel.org/doc/Documentation/sysctl/vm.txt // Each setting is exposed as a single file. // Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array -// and numa_zonelist_order (deprecated) which is a string +// and numa_zonelist_order (deprecated) which is a string. type VM struct { AdminReserveKbytes *int64 // /proc/sys/vm/admin_reserve_kbytes BlockDump *int64 // /proc/sys/vm/block_dump @@ -87,7 +87,7 @@ func (fs FS) VM() (*VM, error) { return nil, fmt.Errorf("%s is not a directory", path) } - files, err := ioutil.ReadDir(path) + files, err := os.ReadDir(path) if err != nil { return nil, err } diff --git a/vendor/github.com/prometheus/procfs/zoneinfo.go b/vendor/github.com/prometheus/procfs/zoneinfo.go index 209e2ac98..c745a4c04 100644 --- a/vendor/github.com/prometheus/procfs/zoneinfo.go +++ b/vendor/github.com/prometheus/procfs/zoneinfo.go @@ -11,6 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +//go:build !windows // +build !windows package procfs @@ -18,7 +19,7 @@ package procfs import ( "bytes" "fmt" - "io/ioutil" + "os" "regexp" "strings" @@ -72,7 +73,7 @@ var nodeZoneRE = regexp.MustCompile(`(\d+), zone\s+(\w+)`) // structs containing the relevant info. More information available here: // https://www.kernel.org/doc/Documentation/sysctl/vm.txt func (fs FS) Zoneinfo() ([]Zoneinfo, error) { - data, err := ioutil.ReadFile(fs.proc.Path("zoneinfo")) + data, err := os.ReadFile(fs.proc.Path("zoneinfo")) if err != nil { return nil, fmt.Errorf("error reading zoneinfo %q: %w", fs.proc.Path("zoneinfo"), err) } diff --git a/vendor/github.com/status-im/go-multiaddr-ethv4/protocol.go b/vendor/github.com/status-im/go-multiaddr-ethv4/protocol.go index 06c323a3f..04c979211 100644 --- a/vendor/github.com/status-im/go-multiaddr-ethv4/protocol.go +++ b/vendor/github.com/status-im/go-multiaddr-ethv4/protocol.go @@ -4,8 +4,8 @@ import ( "errors" "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" mh "github.com/multiformats/go-multihash" diff --git a/vendor/github.com/status-im/go-waku-rendezvous/.gitignore b/vendor/github.com/status-im/go-waku-rendezvous/.gitignore deleted file mode 100644 index a1338d685..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Binaries for programs and plugins -*.exe -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out - -# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 -.glide/ diff --git a/vendor/github.com/status-im/go-waku-rendezvous/LICENSE b/vendor/github.com/status-im/go-waku-rendezvous/LICENSE deleted file mode 100644 index 3f05397b7..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 libp2p - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/status-im/go-waku-rendezvous/README.md b/vendor/github.com/status-im/go-waku-rendezvous/README.md deleted file mode 100644 index 0d7e07450..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/README.md +++ /dev/null @@ -1,157 +0,0 @@ -# Rendezvous Protocol - -### Overview - -Similar to [status-im/rendezvous](https://github.com/status-im/rendezvous) -in using a smaller liveness TTL for records (20s), and not using unregistering -records, due to assuming that the TTL is very low (making it incompatible -with libp2p original rendezvous spec). This module is intended to be used -in go-waku as a lightweight mechanism for generalized peer discovery. - -A difference compared to status-im/rendezvous is the usage of [routing records](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md) and [signed envelopes](https://github.com/libp2p/specs/blob/master/RFC/0002-signed-envelopes.md) instead of ENR records - -**Protocol identifier**: `/vac/waku/rendezvous/0.0.1` - -### Usage - -**Adding discovery to gossipsub** -```go -import ( - "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - pubsub "github.com/status-im/go-libp2p-pubsub" - rendezvous "github.com/status-im/go-waku-rendezvous" -) - -// create a new libp2p Host that listens on a random TCP port -h, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0")) -if err != nil { - panic(err) -} - -// Create a rendezvous instance -rendezvous := rendezvous.NewRendezvousDiscovery(h) - -// create a new PubSub service using the GossipSub router -ps, err := pubsub.NewGossipSub(ctx, h, pubsub.WithDiscovery(rendezvous)) -if err != nil { - panic(err) -} -``` - -**Creating a rendezvous server** -```go -import ( - "database/sql" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" - "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - pubsub "github.com/status-im/go-libp2p-pubsub" - rendezvous "github.com/status-im/go-waku-rendezvous" -) - -type RendezVousLevelDB struct { - db *leveldb.DB -} - -func NewRendezVousLevelDB(dBPath string) (*RendezVousLevelDB, error) { - db, err := leveldb.OpenFile(dBPath, &opt.Options{OpenFilesCacheCapacity: 3}) - - if err != nil { - return nil, err - } - - return &RendezVousLevelDB{db}, nil -} - -func (r *RendezVousLevelDB) Delete(key []byte) error { - return r.db.Delete(key, nil) -} - -func (r *RendezVousLevelDB) Put(key []byte, value []byte) error { - return r.db.Put(key, value, nil) -} - -func (r *RendezVousLevelDB) NewIterator(prefix []byte) rendezvous.Iterator { - return r.db.NewIterator(util.BytesPrefix(prefix), nil) -} - - -// create a new libp2p Host that listens on a random TCP port -h, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/0.0.0.0/tcp/0")) -if err != nil { - panic(err) -} - -// LevelDB storage for peer records -db, err := NewRendezVousLevelDB("/tmp/rendezvous") -if err != nil { - panic(err) -} -storage := rendezvous.NewStorage(db) - -rendezvousService = rendezvous.NewRendezvousService(h, storage) -if err := rendezvousService.Start(); err != nil { - panic(err) -} -``` - -### Protobuf - -- [record.pb.Envelope](https://github.com/libp2p/specs/blob/master/RFC/0002-signed-envelopes.md#wire-format) -- [PeerRecord protobuffer](https://github.com/libp2p/specs/blob/master/RFC/0003-routing-records.md#address-record-format) - -```protobuf -message Message { - enum MessageType { - REGISTER = 0; - REGISTER_RESPONSE = 1; - DISCOVER = 2; - DISCOVER_RESPONSE = 3; - } - - enum ResponseStatus { - OK = 0; - E_INVALID_NAMESPACE = 100; - E_INVALID_PEER_INFO = 101; - E_INVALID_TTL = 102; - E_NOT_AUTHORIZED = 200; - E_INTERNAL_ERROR = 300; - E_UNAVAILABLE = 400; - } - - message Register { - string ns = 1; - bytes signedPeerRecord = 2; - int64 ttl = 3; // in seconds - } - - message RegisterResponse { - ResponseStatus status = 1; - string statusText = 2; - int64 ttl = 3; - } - - message Discover { - string ns = 1; - int64 limit = 2; - } - - message DiscoverResponse { - repeated Register registrations = 1; - ResponseStatus status = 3; - string statusText = 4; - } - - MessageType type = 1; - Register register = 2; - RegisterResponse registerResponse = 3; - Discover discover = 4; - DiscoverResponse discoverResponse = 5; -} - -``` diff --git a/vendor/github.com/status-im/go-waku-rendezvous/cleaner.go b/vendor/github.com/status-im/go-waku-rendezvous/cleaner.go deleted file mode 100644 index 9ef04400c..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/cleaner.go +++ /dev/null @@ -1,104 +0,0 @@ -package rendezvous - -import ( - "container/heap" - "sync" - "time" -) - -type deadline struct { - time time.Time -} - -// definitely rename -// Rewrite cleaner to operate on a leveldb directly -// if it is impossible to query on topic+timestamp(big endian) for purging -// store an additional key -func NewCleaner() *Cleaner { - return &Cleaner{ - heap: []string{}, - deadlines: map[string]deadline{}, - } -} - -type Cleaner struct { - mu sync.RWMutex - heap []string - deadlines map[string]deadline -} - -func (c *Cleaner) Id(index int) string { - return c.heap[index] -} - -func (c *Cleaner) Len() int { - return len(c.heap) -} - -func (c *Cleaner) Less(i, j int) bool { - return c.deadlines[c.Id(i)].time.Before(c.deadlines[c.Id(j)].time) -} - -func (c *Cleaner) Swap(i, j int) { - c.heap[i], c.heap[j] = c.heap[j], c.heap[i] -} - -func (c *Cleaner) Push(record interface{}) { - c.heap = append(c.heap, record.(string)) -} - -func (c *Cleaner) Pop() interface{} { - old := c.heap - n := len(old) - x := old[n-1] - c.heap = append([]string{}, old[0:n-1]...) - _, exist := c.deadlines[x] - if !exist { - return x - } - delete(c.deadlines, x) - return x -} - -func (c *Cleaner) Add(deadlineTime time.Time, key string) { - c.mu.Lock() - defer c.mu.Unlock() - dl, exist := c.deadlines[key] - if !exist { - dl = deadline{time: deadlineTime} - } else { - dl.time = deadlineTime - for i, n := range c.heap { - if n == key { - heap.Remove(c, i) - break - } - } - } - c.deadlines[key] = dl - heap.Push(c, key) -} - -func (c *Cleaner) Exist(key string) bool { - c.mu.RLock() - defer c.mu.RUnlock() - _, exist := c.deadlines[key] - return exist -} - -func (c *Cleaner) PopSince(now time.Time) (rst []string) { - c.mu.Lock() - defer c.mu.Unlock() - for len(c.heap) != 0 { - dl, exist := c.deadlines[c.heap[0]] - if !exist { - continue - } - if now.After(dl.time) { - rst = append(rst, heap.Pop(c).(string)) - } else { - return rst - } - } - return rst -} diff --git a/vendor/github.com/status-im/go-waku-rendezvous/client.go b/vendor/github.com/status-im/go-waku-rendezvous/client.go deleted file mode 100644 index 0d713d048..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/client.go +++ /dev/null @@ -1,352 +0,0 @@ -package rendezvous - -import ( - "context" - "errors" - "fmt" - "math/rand" - "time" - - pb "github.com/status-im/go-waku-rendezvous/pb" - - ggio "github.com/gogo/protobuf/io" - - "github.com/libp2p/go-libp2p-core/host" - inet "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" - "github.com/libp2p/go-libp2p-core/record" -) - -var ( - DiscoverAsyncInterval = 2 * time.Minute -) - -type RendezvousPoint interface { - Register(ctx context.Context, ns string, ttl int) (time.Duration, error) - Discover(ctx context.Context, ns string, limit int) ([]Registration, error) - DiscoverAsync(ctx context.Context, ns string) (<-chan Registration, error) -} - -type Registration struct { - Peer peer.AddrInfo - Ns string - Ttl int -} - -type RendezvousClient interface { - Register(ctx context.Context, ns string, ttl int) (time.Duration, error) - Discover(ctx context.Context, ns string, limit int) ([]peer.AddrInfo, error) - DiscoverAsync(ctx context.Context, ns string) (<-chan peer.AddrInfo, error) -} - -func NewRendezvousPoint(host host.Host) RendezvousPoint { - return &rendezvousPoint{ - host: host, - } -} - -type rendezvousPoint struct { - host host.Host -} - -func NewRendezvousClient(host host.Host) RendezvousClient { - return NewRendezvousClientWithPoint(NewRendezvousPoint(host)) -} - -func NewRendezvousClientWithPoint(rp RendezvousPoint) RendezvousClient { - return &rendezvousClient{rp: rp} -} - -type rendezvousClient struct { - rp RendezvousPoint -} - -func (r *rendezvousPoint) getRandomPeer() (peer.ID, error) { - var peerIDs []peer.ID - for _, peer := range r.host.Peerstore().Peers() { - protocols, err := r.host.Peerstore().SupportsProtocols(peer, string(RendezvousID_v001)) - if err != nil { - log.Error("error obtaining the protocols supported by peers", err) - return "", err - } - if len(protocols) > 0 { - peerIDs = append(peerIDs, peer) - } - } - - if len(peerIDs) == 0 { - return "", errors.New("no peers available") - } - - return peerIDs[rand.Intn(len(peerIDs))], nil // nolint: gosec -} - -func (rp *rendezvousPoint) Register(ctx context.Context, ns string, ttl int) (time.Duration, error) { - randomPeer, err := rp.getRandomPeer() - if err != nil { - return 0, err - } - - s, err := rp.host.NewStream(ctx, randomPeer, RendezvousID_v001) - if err != nil { - return 0, err - } - defer s.Reset() - - r := ggio.NewDelimitedReader(s, inet.MessageSizeMax) - w := ggio.NewDelimitedWriter(s) - - privKey := rp.host.Peerstore().PrivKey(rp.host.ID()) - req, err := newRegisterMessage(privKey, ns, peer.AddrInfo{ID: rp.host.ID(), Addrs: rp.host.Addrs()}, ttl) - if err != nil { - return 0, err - } - - err = w.WriteMsg(req) - if err != nil { - return 0, err - } - - var res pb.Message - err = r.ReadMsg(&res) - if err != nil { - return 0, err - } - - if res.GetType() != pb.Message_REGISTER_RESPONSE { - return 0, fmt.Errorf("Unexpected response: %s", res.GetType().String()) - } - - response := res.GetRegisterResponse() - status := response.GetStatus() - if status != pb.Message_OK { - return 0, RendezvousError{Status: status, Text: res.GetRegisterResponse().GetStatusText()} - } - - return time.Duration(response.Ttl) * time.Second, nil -} - -func (rc *rendezvousClient) Register(ctx context.Context, ns string, ttl int) (time.Duration, error) { - if ttl < 120 { - return 0, fmt.Errorf("registration TTL is too short") - } - - returnedTTL, err := rc.rp.Register(ctx, ns, ttl) - if err != nil { - return 0, err - } - - go registerRefresh(ctx, rc.rp, ns, ttl) - return returnedTTL, nil -} - -func registerRefresh(ctx context.Context, rz RendezvousPoint, ns string, ttl int) { - var refresh time.Duration - errcount := 0 - - for { - if errcount > 0 { - // do randomized exponential backoff, up to ~4 hours - if errcount > 7 { - errcount = 7 - } - backoff := 2 << uint(errcount) - refresh = 5*time.Minute + time.Duration(rand.Intn(backoff*60000))*time.Millisecond - } else { - refresh = time.Duration(ttl-30) * time.Second - } - - select { - case <-time.After(refresh): - case <-ctx.Done(): - return - } - - _, err := rz.Register(ctx, ns, ttl) - if err != nil { - log.Errorf("Error registering [%s]: %s", ns, err.Error()) - errcount++ - } else { - errcount = 0 - } - } -} - -func (rp *rendezvousPoint) Discover(ctx context.Context, ns string, limit int) ([]Registration, error) { - randomPeer, err := rp.getRandomPeer() - if err != nil { - return nil, err - } - - s, err := rp.host.NewStream(ctx, randomPeer, RendezvousID_v001) - if err != nil { - return nil, err - } - defer s.Reset() - - r := ggio.NewDelimitedReader(s, inet.MessageSizeMax) - w := ggio.NewDelimitedWriter(s) - - return rp.discoverQuery(ns, limit, r, w) -} - -func (rp *rendezvousPoint) discoverQuery(ns string, limit int, r ggio.Reader, w ggio.Writer) ([]Registration, error) { - req := newDiscoverMessage(ns, limit) - err := w.WriteMsg(req) - if err != nil { - return nil, err - } - - var res pb.Message - err = r.ReadMsg(&res) - if err != nil { - return nil, err - } - - if res.GetType() != pb.Message_DISCOVER_RESPONSE { - return nil, fmt.Errorf("unexpected response: %s", res.GetType().String()) - } - - status := res.GetDiscoverResponse().GetStatus() - if status != pb.Message_OK { - return nil, RendezvousError{Status: status, Text: res.GetDiscoverResponse().GetStatusText()} - } - - regs := res.GetDiscoverResponse().GetRegistrations() - result := make([]Registration, 0, len(regs)) - for _, reg := range regs { - - reg.GetSignedPeerRecord() - envelope, err := record.UnmarshalEnvelope(reg.GetSignedPeerRecord()) - if err != nil { - log.Errorf("Invalid peer info: %s", err.Error()) - continue - } - - cab, ok := peerstore.GetCertifiedAddrBook(rp.host.Peerstore()) - if !ok { - return nil, errors.New("a certified addr book is required") - } - - _, err = cab.ConsumePeerRecord(envelope, time.Duration(reg.Ttl)) - if err != nil { - log.Errorf("Invalid peer info: %s", err.Error()) - continue - } - - var record peer.PeerRecord - err = envelope.TypedRecord(&record) - if err != nil { - log.Errorf("Invalid peer record: %s", err.Error()) - continue - } - - result = append(result, Registration{Peer: peer.AddrInfo{ID: record.PeerID, Addrs: record.Addrs}, Ns: reg.GetNs(), Ttl: int(reg.GetTtl())}) - } - - return result, nil -} - -func (rp *rendezvousPoint) DiscoverAsync(ctx context.Context, ns string) (<-chan Registration, error) { - randomPeer, err := rp.getRandomPeer() - if err != nil { - return nil, err - } - - s, err := rp.host.NewStream(ctx, randomPeer, RendezvousID_v001) - if err != nil { - return nil, err - } - - ch := make(chan Registration) - go rp.discoverAsync(ctx, ns, s, ch) - return ch, nil -} - -func (rp *rendezvousPoint) discoverAsync(ctx context.Context, ns string, s inet.Stream, ch chan Registration) { - defer s.Reset() - defer close(ch) - - r := ggio.NewDelimitedReader(s, inet.MessageSizeMax) - w := ggio.NewDelimitedWriter(s) - - const batch = 200 - - var ( - regs []Registration - err error - ) - - for { - regs, err = rp.discoverQuery(ns, batch, r, w) - if err != nil { - // TODO robust error recovery - // - handle closed streams with backoff + new stream - log.Errorf("Error in discovery [%s]: %s", ns, err.Error()) - return - } - - for _, reg := range regs { - select { - case ch <- reg: - case <-ctx.Done(): - return - } - } - - if len(regs) < batch { - // TODO adaptive backoff for heavily loaded rendezvous points - select { - case <-time.After(DiscoverAsyncInterval): - case <-ctx.Done(): - return - } - } - } -} - -func (rc *rendezvousClient) Discover(ctx context.Context, ns string, limit int) ([]peer.AddrInfo, error) { - regs, err := rc.rp.Discover(ctx, ns, limit) - if err != nil { - return nil, err - } - - pinfos := make([]peer.AddrInfo, len(regs)) - for i, reg := range regs { - pinfos[i] = reg.Peer - } - - return pinfos, nil -} - -func (rc *rendezvousClient) DiscoverAsync(ctx context.Context, ns string) (<-chan peer.AddrInfo, error) { - rch, err := rc.rp.DiscoverAsync(ctx, ns) - if err != nil { - return nil, err - } - - ch := make(chan peer.AddrInfo) - go discoverPeersAsync(ctx, rch, ch) - return ch, nil -} - -func discoverPeersAsync(ctx context.Context, rch <-chan Registration, ch chan peer.AddrInfo) { - defer close(ch) - for { - select { - case reg, ok := <-rch: - if !ok { - return - } - - select { - case ch <- reg.Peer: - case <-ctx.Done(): - return - } - case <-ctx.Done(): - return - } - } -} diff --git a/vendor/github.com/status-im/go-waku-rendezvous/discovery.go b/vendor/github.com/status-im/go-waku-rendezvous/discovery.go deleted file mode 100644 index 9dfa77945..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/discovery.go +++ /dev/null @@ -1,151 +0,0 @@ -package rendezvous - -import ( - "context" - "math" - "math/rand" - "sync" - "time" - - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" -) - -type rendezvousDiscovery struct { - rp RendezvousPoint - peerCache map[string]*discoveryCache - peerCacheMux sync.RWMutex - rng *rand.Rand - rngMux sync.Mutex -} - -type discoveryCache struct { - recs map[peer.ID]*peerRecord - mux sync.Mutex -} - -type peerRecord struct { - peer peer.AddrInfo - expire int64 -} - -func NewRendezvousDiscovery(host host.Host) discovery.Discovery { - rp := NewRendezvousPoint(host) - return &rendezvousDiscovery{rp: rp, peerCache: make(map[string]*discoveryCache), rng: rand.New(rand.NewSource(rand.Int63()))} -} - -func (c *rendezvousDiscovery) Advertise(ctx context.Context, ns string, opts ...discovery.Option) (time.Duration, error) { - // Get options - var options discovery.Options - err := options.Apply(opts...) - if err != nil { - return 0, err - } - - ttl := options.Ttl - var ttlSeconds int - - if ttl == 0 { - ttlSeconds = MaxTTL - } else { - ttlSeconds = int(math.Round(ttl.Seconds())) - } - - if rttl, err := c.rp.Register(ctx, ns, ttlSeconds); err != nil { - return 0, err - } else { - return rttl, nil - } -} - -func (c *rendezvousDiscovery) FindPeers(ctx context.Context, ns string, opts ...discovery.Option) (<-chan peer.AddrInfo, error) { - // Get options - var options discovery.Options - err := options.Apply(opts...) - if err != nil { - return nil, err - } - - const maxLimit = 50 - limit := options.Limit - if limit == 0 || limit > maxLimit { - limit = maxLimit - } - - // Get cached peers - var cache *discoveryCache - - c.peerCacheMux.RLock() - cache, ok := c.peerCache[ns] - c.peerCacheMux.RUnlock() - if !ok { - c.peerCacheMux.Lock() - cache, ok = c.peerCache[ns] - if !ok { - cache = &discoveryCache{recs: make(map[peer.ID]*peerRecord)} - c.peerCache[ns] = cache - } - c.peerCacheMux.Unlock() - } - - cache.mux.Lock() - defer cache.mux.Unlock() - - // Remove all expired entries from cache - currentTime := time.Now().Unix() - newCacheSize := len(cache.recs) - - for p := range cache.recs { - rec := cache.recs[p] - if rec.expire < currentTime { - newCacheSize-- - delete(cache.recs, p) - } - } - - // Discover new records if we don't have enough - if newCacheSize < limit { - // TODO: Should we return error even if we have valid cached results? - var regs []Registration - if regs, err = c.rp.Discover(ctx, ns, limit); err == nil { - for _, reg := range regs { - rec := &peerRecord{peer: reg.Peer, expire: int64(reg.Ttl) + currentTime} - cache.recs[rec.peer.ID] = rec - } - } - } - - // Randomize and fill channel with available records - count := len(cache.recs) - if limit < count { - count = limit - } - - chPeer := make(chan peer.AddrInfo, count) - - c.rngMux.Lock() - perm := c.rng.Perm(len(cache.recs))[0:count] - c.rngMux.Unlock() - - permSet := make(map[int]int) - for i, v := range perm { - permSet[v] = i - } - - sendLst := make([]*peer.AddrInfo, count) - iter := 0 - for k := range cache.recs { - if sendIndex, ok := permSet[iter]; ok { - sendLst[sendIndex] = &cache.recs[k].peer - } - iter++ - } - - for _, send := range sendLst { - chPeer <- *send - } - - close(chPeer) - return chPeer, err -} diff --git a/vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.pb.go b/vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.pb.go deleted file mode 100644 index 5b6260139..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.pb.go +++ /dev/null @@ -1,1659 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: rendezvous.proto - -package rendezvous_pb - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -type Message_MessageType int32 - -const ( - Message_REGISTER Message_MessageType = 0 - Message_REGISTER_RESPONSE Message_MessageType = 1 - Message_DISCOVER Message_MessageType = 2 - Message_DISCOVER_RESPONSE Message_MessageType = 3 -) - -var Message_MessageType_name = map[int32]string{ - 0: "REGISTER", - 1: "REGISTER_RESPONSE", - 2: "DISCOVER", - 3: "DISCOVER_RESPONSE", -} - -var Message_MessageType_value = map[string]int32{ - "REGISTER": 0, - "REGISTER_RESPONSE": 1, - "DISCOVER": 2, - "DISCOVER_RESPONSE": 3, -} - -func (x Message_MessageType) String() string { - return proto.EnumName(Message_MessageType_name, int32(x)) -} - -func (Message_MessageType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_ef0a1d5737df1c36, []int{0, 0} -} - -type Message_ResponseStatus int32 - -const ( - Message_OK Message_ResponseStatus = 0 - Message_E_INVALID_NAMESPACE Message_ResponseStatus = 100 - Message_E_INVALID_PEER_INFO Message_ResponseStatus = 101 - Message_E_INVALID_TTL Message_ResponseStatus = 102 - Message_E_NOT_AUTHORIZED Message_ResponseStatus = 200 - Message_E_INTERNAL_ERROR Message_ResponseStatus = 300 - Message_E_UNAVAILABLE Message_ResponseStatus = 400 -) - -var Message_ResponseStatus_name = map[int32]string{ - 0: "OK", - 100: "E_INVALID_NAMESPACE", - 101: "E_INVALID_PEER_INFO", - 102: "E_INVALID_TTL", - 200: "E_NOT_AUTHORIZED", - 300: "E_INTERNAL_ERROR", - 400: "E_UNAVAILABLE", -} - -var Message_ResponseStatus_value = map[string]int32{ - "OK": 0, - "E_INVALID_NAMESPACE": 100, - "E_INVALID_PEER_INFO": 101, - "E_INVALID_TTL": 102, - "E_NOT_AUTHORIZED": 200, - "E_INTERNAL_ERROR": 300, - "E_UNAVAILABLE": 400, -} - -func (x Message_ResponseStatus) String() string { - return proto.EnumName(Message_ResponseStatus_name, int32(x)) -} - -func (Message_ResponseStatus) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_ef0a1d5737df1c36, []int{0, 1} -} - -type Message struct { - Type Message_MessageType `protobuf:"varint,1,opt,name=type,proto3,enum=rendezvous.pb.Message_MessageType" json:"type,omitempty"` - Register *Message_Register `protobuf:"bytes,2,opt,name=register,proto3" json:"register,omitempty"` - RegisterResponse *Message_RegisterResponse `protobuf:"bytes,3,opt,name=registerResponse,proto3" json:"registerResponse,omitempty"` - Discover *Message_Discover `protobuf:"bytes,4,opt,name=discover,proto3" json:"discover,omitempty"` - DiscoverResponse *Message_DiscoverResponse `protobuf:"bytes,5,opt,name=discoverResponse,proto3" json:"discoverResponse,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Message) Reset() { *m = Message{} } -func (m *Message) String() string { return proto.CompactTextString(m) } -func (*Message) ProtoMessage() {} -func (*Message) Descriptor() ([]byte, []int) { - return fileDescriptor_ef0a1d5737df1c36, []int{0} -} -func (m *Message) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Message.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Message) XXX_Merge(src proto.Message) { - xxx_messageInfo_Message.Merge(m, src) -} -func (m *Message) XXX_Size() int { - return m.Size() -} -func (m *Message) XXX_DiscardUnknown() { - xxx_messageInfo_Message.DiscardUnknown(m) -} - -var xxx_messageInfo_Message proto.InternalMessageInfo - -func (m *Message) GetType() Message_MessageType { - if m != nil { - return m.Type - } - return Message_REGISTER -} - -func (m *Message) GetRegister() *Message_Register { - if m != nil { - return m.Register - } - return nil -} - -func (m *Message) GetRegisterResponse() *Message_RegisterResponse { - if m != nil { - return m.RegisterResponse - } - return nil -} - -func (m *Message) GetDiscover() *Message_Discover { - if m != nil { - return m.Discover - } - return nil -} - -func (m *Message) GetDiscoverResponse() *Message_DiscoverResponse { - if m != nil { - return m.DiscoverResponse - } - return nil -} - -type Message_Register struct { - Ns string `protobuf:"bytes,1,opt,name=ns,proto3" json:"ns,omitempty"` - SignedPeerRecord []byte `protobuf:"bytes,2,opt,name=signedPeerRecord,proto3" json:"signedPeerRecord,omitempty"` - Ttl int64 `protobuf:"varint,3,opt,name=ttl,proto3" json:"ttl,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Message_Register) Reset() { *m = Message_Register{} } -func (m *Message_Register) String() string { return proto.CompactTextString(m) } -func (*Message_Register) ProtoMessage() {} -func (*Message_Register) Descriptor() ([]byte, []int) { - return fileDescriptor_ef0a1d5737df1c36, []int{0, 0} -} -func (m *Message_Register) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Message_Register) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Message_Register.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Message_Register) XXX_Merge(src proto.Message) { - xxx_messageInfo_Message_Register.Merge(m, src) -} -func (m *Message_Register) XXX_Size() int { - return m.Size() -} -func (m *Message_Register) XXX_DiscardUnknown() { - xxx_messageInfo_Message_Register.DiscardUnknown(m) -} - -var xxx_messageInfo_Message_Register proto.InternalMessageInfo - -func (m *Message_Register) GetNs() string { - if m != nil { - return m.Ns - } - return "" -} - -func (m *Message_Register) GetSignedPeerRecord() []byte { - if m != nil { - return m.SignedPeerRecord - } - return nil -} - -func (m *Message_Register) GetTtl() int64 { - if m != nil { - return m.Ttl - } - return 0 -} - -type Message_RegisterResponse struct { - Status Message_ResponseStatus `protobuf:"varint,1,opt,name=status,proto3,enum=rendezvous.pb.Message_ResponseStatus" json:"status,omitempty"` - StatusText string `protobuf:"bytes,2,opt,name=statusText,proto3" json:"statusText,omitempty"` - Ttl int64 `protobuf:"varint,3,opt,name=ttl,proto3" json:"ttl,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Message_RegisterResponse) Reset() { *m = Message_RegisterResponse{} } -func (m *Message_RegisterResponse) String() string { return proto.CompactTextString(m) } -func (*Message_RegisterResponse) ProtoMessage() {} -func (*Message_RegisterResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ef0a1d5737df1c36, []int{0, 1} -} -func (m *Message_RegisterResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Message_RegisterResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Message_RegisterResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Message_RegisterResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_Message_RegisterResponse.Merge(m, src) -} -func (m *Message_RegisterResponse) XXX_Size() int { - return m.Size() -} -func (m *Message_RegisterResponse) XXX_DiscardUnknown() { - xxx_messageInfo_Message_RegisterResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_Message_RegisterResponse proto.InternalMessageInfo - -func (m *Message_RegisterResponse) GetStatus() Message_ResponseStatus { - if m != nil { - return m.Status - } - return Message_OK -} - -func (m *Message_RegisterResponse) GetStatusText() string { - if m != nil { - return m.StatusText - } - return "" -} - -func (m *Message_RegisterResponse) GetTtl() int64 { - if m != nil { - return m.Ttl - } - return 0 -} - -type Message_Discover struct { - Ns string `protobuf:"bytes,1,opt,name=ns,proto3" json:"ns,omitempty"` - Limit int64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Message_Discover) Reset() { *m = Message_Discover{} } -func (m *Message_Discover) String() string { return proto.CompactTextString(m) } -func (*Message_Discover) ProtoMessage() {} -func (*Message_Discover) Descriptor() ([]byte, []int) { - return fileDescriptor_ef0a1d5737df1c36, []int{0, 2} -} -func (m *Message_Discover) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Message_Discover) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Message_Discover.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Message_Discover) XXX_Merge(src proto.Message) { - xxx_messageInfo_Message_Discover.Merge(m, src) -} -func (m *Message_Discover) XXX_Size() int { - return m.Size() -} -func (m *Message_Discover) XXX_DiscardUnknown() { - xxx_messageInfo_Message_Discover.DiscardUnknown(m) -} - -var xxx_messageInfo_Message_Discover proto.InternalMessageInfo - -func (m *Message_Discover) GetNs() string { - if m != nil { - return m.Ns - } - return "" -} - -func (m *Message_Discover) GetLimit() int64 { - if m != nil { - return m.Limit - } - return 0 -} - -type Message_DiscoverResponse struct { - Registrations []*Message_Register `protobuf:"bytes,1,rep,name=registrations,proto3" json:"registrations,omitempty"` - Status Message_ResponseStatus `protobuf:"varint,3,opt,name=status,proto3,enum=rendezvous.pb.Message_ResponseStatus" json:"status,omitempty"` - StatusText string `protobuf:"bytes,4,opt,name=statusText,proto3" json:"statusText,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Message_DiscoverResponse) Reset() { *m = Message_DiscoverResponse{} } -func (m *Message_DiscoverResponse) String() string { return proto.CompactTextString(m) } -func (*Message_DiscoverResponse) ProtoMessage() {} -func (*Message_DiscoverResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_ef0a1d5737df1c36, []int{0, 3} -} -func (m *Message_DiscoverResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Message_DiscoverResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Message_DiscoverResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Message_DiscoverResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_Message_DiscoverResponse.Merge(m, src) -} -func (m *Message_DiscoverResponse) XXX_Size() int { - return m.Size() -} -func (m *Message_DiscoverResponse) XXX_DiscardUnknown() { - xxx_messageInfo_Message_DiscoverResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_Message_DiscoverResponse proto.InternalMessageInfo - -func (m *Message_DiscoverResponse) GetRegistrations() []*Message_Register { - if m != nil { - return m.Registrations - } - return nil -} - -func (m *Message_DiscoverResponse) GetStatus() Message_ResponseStatus { - if m != nil { - return m.Status - } - return Message_OK -} - -func (m *Message_DiscoverResponse) GetStatusText() string { - if m != nil { - return m.StatusText - } - return "" -} - -func init() { - proto.RegisterEnum("rendezvous.pb.Message_MessageType", Message_MessageType_name, Message_MessageType_value) - proto.RegisterEnum("rendezvous.pb.Message_ResponseStatus", Message_ResponseStatus_name, Message_ResponseStatus_value) - proto.RegisterType((*Message)(nil), "rendezvous.pb.Message") - proto.RegisterType((*Message_Register)(nil), "rendezvous.pb.Message.Register") - proto.RegisterType((*Message_RegisterResponse)(nil), "rendezvous.pb.Message.RegisterResponse") - proto.RegisterType((*Message_Discover)(nil), "rendezvous.pb.Message.Discover") - proto.RegisterType((*Message_DiscoverResponse)(nil), "rendezvous.pb.Message.DiscoverResponse") -} - -func init() { proto.RegisterFile("rendezvous.proto", fileDescriptor_ef0a1d5737df1c36) } - -var fileDescriptor_ef0a1d5737df1c36 = []byte{ - // 528 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x54, 0xcd, 0x6e, 0xd3, 0x4c, - 0x14, 0xcd, 0xd8, 0x69, 0xbe, 0xf4, 0xb6, 0x89, 0xa6, 0xf3, 0x51, 0x11, 0x65, 0x61, 0xaa, 0x48, - 0x88, 0x8a, 0x45, 0x84, 0x8a, 0xc4, 0x06, 0xb1, 0x70, 0xeb, 0x01, 0x2c, 0x5c, 0x3b, 0xba, 0x76, - 0x03, 0x62, 0x63, 0xa5, 0xf5, 0x10, 0x59, 0x2a, 0x76, 0xe4, 0x71, 0x2b, 0xca, 0x96, 0x17, 0x60, - 0xc9, 0x8e, 0x17, 0x80, 0x3d, 0x8f, 0xd0, 0x25, 0x8f, 0x80, 0xc2, 0x8b, 0x20, 0xff, 0xa5, 0xf9, - 0xa1, 0x05, 0x89, 0x95, 0xef, 0xbd, 0x73, 0xce, 0xd1, 0xb9, 0x67, 0x6c, 0x03, 0x4d, 0x44, 0x14, - 0x88, 0xf7, 0xe7, 0xf1, 0x99, 0xec, 0x4f, 0x92, 0x38, 0x8d, 0x59, 0x6b, 0x7e, 0x72, 0xdc, 0xfb, - 0xda, 0x84, 0xff, 0x0e, 0x85, 0x94, 0xa3, 0xb1, 0x60, 0x8f, 0xa0, 0x9e, 0x5e, 0x4c, 0x44, 0x87, - 0xec, 0x90, 0xdd, 0xf6, 0x5e, 0xaf, 0xbf, 0x80, 0xec, 0x97, 0xa8, 0xea, 0xe9, 0x5d, 0x4c, 0x04, - 0xe6, 0x78, 0xf6, 0x18, 0x9a, 0x89, 0x18, 0x87, 0x32, 0x15, 0x49, 0x47, 0xd9, 0x21, 0xbb, 0x1b, - 0x7b, 0x77, 0xae, 0xe1, 0x62, 0x09, 0xc3, 0x19, 0x81, 0xb9, 0x99, 0xc7, 0x72, 0x2a, 0xe4, 0x24, - 0x8e, 0xa4, 0xe8, 0xa8, 0xb9, 0xc8, 0xbd, 0x3f, 0x89, 0x94, 0x70, 0x5c, 0x11, 0xc8, 0x1c, 0x05, - 0xa1, 0x3c, 0x89, 0xcf, 0x45, 0xd2, 0xa9, 0xdf, 0xe8, 0xc8, 0x28, 0x61, 0x38, 0x23, 0x64, 0x8e, - 0xaa, 0x7a, 0xe6, 0x68, 0xed, 0x46, 0x47, 0xc6, 0x12, 0x1c, 0x57, 0x04, 0xba, 0xaf, 0xa0, 0x59, - 0xf9, 0x66, 0x6d, 0x50, 0x22, 0x99, 0xa7, 0xbc, 0x8e, 0x4a, 0x24, 0xd9, 0x7d, 0xa0, 0x32, 0x1c, - 0x47, 0x22, 0x18, 0x88, 0x8c, 0x71, 0x12, 0x27, 0x41, 0x9e, 0xe3, 0x26, 0xae, 0xcc, 0x19, 0x05, - 0x35, 0x4d, 0x4f, 0xf3, 0x84, 0x54, 0xcc, 0xca, 0xee, 0x07, 0x02, 0x74, 0x39, 0x12, 0xf6, 0x04, - 0x1a, 0x32, 0x1d, 0xa5, 0x67, 0xb2, 0xbc, 0xcc, 0xbb, 0xd7, 0x66, 0x59, 0x10, 0xdc, 0x1c, 0x8c, - 0x25, 0x89, 0x69, 0x00, 0x45, 0xe5, 0x89, 0x77, 0x69, 0xee, 0x65, 0x1d, 0xe7, 0x26, 0xbf, 0x71, - 0xf1, 0x00, 0x9a, 0x55, 0x0a, 0x2b, 0xfb, 0xdd, 0x82, 0xb5, 0xd3, 0xf0, 0x6d, 0x58, 0x08, 0xa9, - 0x58, 0x34, 0xdd, 0x6f, 0x04, 0xe8, 0x72, 0x70, 0x8c, 0x43, 0xab, 0xb8, 0xcc, 0x64, 0x94, 0x86, - 0x71, 0xae, 0xa2, 0xfe, 0xcd, 0xfb, 0xb4, 0xc8, 0x9a, 0x5b, 0x5f, 0xfd, 0xf7, 0xf5, 0xeb, 0xcb, - 0xeb, 0xf7, 0x5e, 0xc2, 0xc6, 0xdc, 0x57, 0xc0, 0x36, 0xa1, 0x89, 0xfc, 0x99, 0xe9, 0x7a, 0x1c, - 0x69, 0x8d, 0x6d, 0xc3, 0x56, 0xd5, 0xf9, 0xc8, 0xdd, 0x81, 0x63, 0xbb, 0x9c, 0x92, 0x0c, 0x64, - 0x98, 0xee, 0x81, 0x33, 0xe4, 0x48, 0x95, 0x0c, 0x54, 0x75, 0x57, 0x20, 0xb5, 0xf7, 0x99, 0x40, - 0x7b, 0xd1, 0x13, 0x6b, 0x80, 0xe2, 0xbc, 0xa0, 0x35, 0x76, 0x1b, 0xfe, 0xe7, 0xbe, 0x69, 0x0f, - 0x75, 0xcb, 0x34, 0x7c, 0x5b, 0x3f, 0xe4, 0xee, 0x40, 0x3f, 0xe0, 0x34, 0x58, 0x3c, 0x18, 0x70, - 0x8e, 0xbe, 0x69, 0x3f, 0x75, 0xa8, 0x60, 0x5b, 0xd0, 0xba, 0x3a, 0xf0, 0x3c, 0x8b, 0xbe, 0x61, - 0xdb, 0x40, 0xb9, 0x6f, 0x3b, 0x9e, 0xaf, 0x1f, 0x79, 0xcf, 0x1d, 0x34, 0x5f, 0x73, 0x83, 0x5e, - 0x92, 0x62, 0x6c, 0xda, 0x1e, 0x47, 0x5b, 0xb7, 0x7c, 0x8e, 0xe8, 0x20, 0xfd, 0xa2, 0x30, 0x96, - 0x09, 0x1c, 0xd9, 0xfa, 0x50, 0x37, 0x2d, 0x7d, 0xdf, 0xe2, 0xf4, 0xa3, 0xba, 0x4f, 0x2f, 0xa7, - 0x1a, 0xf9, 0x3e, 0xd5, 0xc8, 0x8f, 0xa9, 0x46, 0x3e, 0xfd, 0xd4, 0x6a, 0xc7, 0x8d, 0xfc, 0xbf, - 0xf2, 0xf0, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x4c, 0x11, 0x6e, 0xa0, 0x6b, 0x04, 0x00, 0x00, -} - -func (m *Message) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Message) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Message) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if m.DiscoverResponse != nil { - { - size, err := m.DiscoverResponse.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintRendezvous(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x2a - } - if m.Discover != nil { - { - size, err := m.Discover.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintRendezvous(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x22 - } - if m.RegisterResponse != nil { - { - size, err := m.RegisterResponse.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintRendezvous(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a - } - if m.Register != nil { - { - size, err := m.Register.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintRendezvous(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if m.Type != 0 { - i = encodeVarintRendezvous(dAtA, i, uint64(m.Type)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *Message_Register) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Message_Register) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Message_Register) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if m.Ttl != 0 { - i = encodeVarintRendezvous(dAtA, i, uint64(m.Ttl)) - i-- - dAtA[i] = 0x18 - } - if len(m.SignedPeerRecord) > 0 { - i -= len(m.SignedPeerRecord) - copy(dAtA[i:], m.SignedPeerRecord) - i = encodeVarintRendezvous(dAtA, i, uint64(len(m.SignedPeerRecord))) - i-- - dAtA[i] = 0x12 - } - if len(m.Ns) > 0 { - i -= len(m.Ns) - copy(dAtA[i:], m.Ns) - i = encodeVarintRendezvous(dAtA, i, uint64(len(m.Ns))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Message_RegisterResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Message_RegisterResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Message_RegisterResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if m.Ttl != 0 { - i = encodeVarintRendezvous(dAtA, i, uint64(m.Ttl)) - i-- - dAtA[i] = 0x18 - } - if len(m.StatusText) > 0 { - i -= len(m.StatusText) - copy(dAtA[i:], m.StatusText) - i = encodeVarintRendezvous(dAtA, i, uint64(len(m.StatusText))) - i-- - dAtA[i] = 0x12 - } - if m.Status != 0 { - i = encodeVarintRendezvous(dAtA, i, uint64(m.Status)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func (m *Message_Discover) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Message_Discover) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Message_Discover) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if m.Limit != 0 { - i = encodeVarintRendezvous(dAtA, i, uint64(m.Limit)) - i-- - dAtA[i] = 0x10 - } - if len(m.Ns) > 0 { - i -= len(m.Ns) - copy(dAtA[i:], m.Ns) - i = encodeVarintRendezvous(dAtA, i, uint64(len(m.Ns))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func (m *Message_DiscoverResponse) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Message_DiscoverResponse) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Message_DiscoverResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if m.XXX_unrecognized != nil { - i -= len(m.XXX_unrecognized) - copy(dAtA[i:], m.XXX_unrecognized) - } - if len(m.StatusText) > 0 { - i -= len(m.StatusText) - copy(dAtA[i:], m.StatusText) - i = encodeVarintRendezvous(dAtA, i, uint64(len(m.StatusText))) - i-- - dAtA[i] = 0x22 - } - if m.Status != 0 { - i = encodeVarintRendezvous(dAtA, i, uint64(m.Status)) - i-- - dAtA[i] = 0x18 - } - if len(m.Registrations) > 0 { - for iNdEx := len(m.Registrations) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Registrations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintRendezvous(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func encodeVarintRendezvous(dAtA []byte, offset int, v uint64) int { - offset -= sovRendezvous(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Message) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Type != 0 { - n += 1 + sovRendezvous(uint64(m.Type)) - } - if m.Register != nil { - l = m.Register.Size() - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.RegisterResponse != nil { - l = m.RegisterResponse.Size() - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.Discover != nil { - l = m.Discover.Size() - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.DiscoverResponse != nil { - l = m.DiscoverResponse.Size() - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *Message_Register) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Ns) - if l > 0 { - n += 1 + l + sovRendezvous(uint64(l)) - } - l = len(m.SignedPeerRecord) - if l > 0 { - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.Ttl != 0 { - n += 1 + sovRendezvous(uint64(m.Ttl)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *Message_RegisterResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Status != 0 { - n += 1 + sovRendezvous(uint64(m.Status)) - } - l = len(m.StatusText) - if l > 0 { - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.Ttl != 0 { - n += 1 + sovRendezvous(uint64(m.Ttl)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *Message_Discover) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Ns) - if l > 0 { - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.Limit != 0 { - n += 1 + sovRendezvous(uint64(m.Limit)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func (m *Message_DiscoverResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Registrations) > 0 { - for _, e := range m.Registrations { - l = e.Size() - n += 1 + l + sovRendezvous(uint64(l)) - } - } - if m.Status != 0 { - n += 1 + sovRendezvous(uint64(m.Status)) - } - l = len(m.StatusText) - if l > 0 { - n += 1 + l + sovRendezvous(uint64(l)) - } - if m.XXX_unrecognized != nil { - n += len(m.XXX_unrecognized) - } - return n -} - -func sovRendezvous(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozRendezvous(x uint64) (n int) { - return sovRendezvous(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Message) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Message: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) - } - m.Type = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Type |= Message_MessageType(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Register", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Register == nil { - m.Register = &Message_Register{} - } - if err := m.Register.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field RegisterResponse", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.RegisterResponse == nil { - m.RegisterResponse = &Message_RegisterResponse{} - } - if err := m.RegisterResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Discover", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Discover == nil { - m.Discover = &Message_Discover{} - } - if err := m.Discover.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DiscoverResponse", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.DiscoverResponse == nil { - m.DiscoverResponse = &Message_DiscoverResponse{} - } - if err := m.DiscoverResponse.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipRendezvous(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthRendezvous - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Message_Register) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Register: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Register: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ns", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ns = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field SignedPeerRecord", wireType) - } - var byteLen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - byteLen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if byteLen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SignedPeerRecord = append(m.SignedPeerRecord[:0], dAtA[iNdEx:postIndex]...) - if m.SignedPeerRecord == nil { - m.SignedPeerRecord = []byte{} - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) - } - m.Ttl = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Ttl |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipRendezvous(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthRendezvous - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Message_RegisterResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RegisterResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RegisterResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - m.Status = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Status |= Message_ResponseStatus(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StatusText", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.StatusText = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) - } - m.Ttl = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Ttl |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipRendezvous(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthRendezvous - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Message_Discover) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Discover: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Discover: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Ns", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Ns = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) - } - m.Limit = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Limit |= int64(b&0x7F) << shift - if b < 0x80 { - break - } - } - default: - iNdEx = preIndex - skippy, err := skipRendezvous(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthRendezvous - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *Message_DiscoverResponse) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: DiscoverResponse: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: DiscoverResponse: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Registrations", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Registrations = append(m.Registrations, &Message_Register{}) - if err := m.Registrations[len(m.Registrations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 3: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) - } - m.Status = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.Status |= Message_ResponseStatus(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field StatusText", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRendezvous - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthRendezvous - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthRendezvous - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.StatusText = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipRendezvous(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthRendezvous - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipRendezvous(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowRendezvous - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowRendezvous - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowRendezvous - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthRendezvous - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupRendezvous - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthRendezvous - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthRendezvous = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowRendezvous = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupRendezvous = fmt.Errorf("proto: unexpected end of group") -) diff --git a/vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.proto b/vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.proto deleted file mode 100644 index 1dd7465ee..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/pb/rendezvous.proto +++ /dev/null @@ -1,51 +0,0 @@ -syntax = "proto3"; - -package rendezvous.pb; - -message Message { - enum MessageType { - REGISTER = 0; - REGISTER_RESPONSE = 1; - DISCOVER = 2; - DISCOVER_RESPONSE = 3; - } - - enum ResponseStatus { - OK = 0; - E_INVALID_NAMESPACE = 100; - E_INVALID_PEER_INFO = 101; - E_INVALID_TTL = 102; - E_NOT_AUTHORIZED = 200; - E_INTERNAL_ERROR = 300; - E_UNAVAILABLE = 400; - } - - message Register { - string ns = 1; - bytes signedPeerRecord = 2; - int64 ttl = 3; // in seconds - } - - message RegisterResponse { - ResponseStatus status = 1; - string statusText = 2; - int64 ttl = 3; - } - - message Discover { - string ns = 1; - int64 limit = 2; - } - - message DiscoverResponse { - repeated Register registrations = 1; - ResponseStatus status = 3; - string statusText = 4; - } - - MessageType type = 1; - Register register = 2; - RegisterResponse registerResponse = 3; - Discover discover = 4; - DiscoverResponse discoverResponse = 5; -} diff --git a/vendor/github.com/status-im/go-waku-rendezvous/proto.go b/vendor/github.com/status-im/go-waku-rendezvous/proto.go deleted file mode 100644 index 2d66b8517..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/proto.go +++ /dev/null @@ -1,139 +0,0 @@ -package rendezvous - -import ( - "errors" - "fmt" - "time" - - libp2pCrypto "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/record" - - pb "github.com/status-im/go-waku-rendezvous/pb" - - logging "github.com/ipfs/go-log/v2" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/protocol" -) - -var log = logging.Logger("rendezvous") - -const ( - RendezvousID_v001 = protocol.ID("/vac/waku/rendezvous/0.0.1") - DefaultTTL = 20 // 20 seconds -) - -type RendezvousError struct { - Status pb.Message_ResponseStatus - Text string -} - -func (e RendezvousError) Error() string { - return fmt.Sprintf("Rendezvous error: %s (%s)", e.Text, pb.Message_ResponseStatus(e.Status).String()) -} - -func newRegisterMessage(privKey libp2pCrypto.PrivKey, ns string, pi peer.AddrInfo, ttl int) (*pb.Message, error) { - msg := new(pb.Message) - msg.Type = pb.Message_REGISTER - msg.Register = new(pb.Message_Register) - if ns != "" { - msg.Register.Ns = ns - } - if ttl > 0 { - ttl64 := int64(ttl) - msg.Register.Ttl = ttl64 - } - - peerRecord := &peer.PeerRecord{ - PeerID: pi.ID, - Addrs: pi.Addrs, - Seq: uint64(time.Now().Unix()), - } - - envelope, err := record.Seal(peerRecord, privKey) - if err != nil { - return nil, err - } - - envPayload, err := envelope.Marshal() - if err != nil { - return nil, err - } - - msg.Register.SignedPeerRecord = envPayload - - return msg, nil -} - -func newDiscoverMessage(ns string, limit int) *pb.Message { - msg := new(pb.Message) - msg.Type = pb.Message_DISCOVER - msg.Discover = new(pb.Message_Discover) - if ns != "" { - msg.Discover.Ns = ns - } - if limit > 0 { - limit64 := int64(limit) - msg.Discover.Limit = limit64 - } - return msg -} - -func unmarshalSignedPeerRecord(envelopeBytes []byte) (peer.AddrInfo, error) { - envelope, rec, err := record.ConsumeEnvelope(envelopeBytes, peer.PeerRecordEnvelopeDomain) - if err != nil { - return peer.AddrInfo{}, err - } - - peerRecord, ok := rec.(*peer.PeerRecord) - if !ok { - return peer.AddrInfo{}, errors.New("invalid peer record") - } - - if !peerRecord.PeerID.MatchesPublicKey(envelope.PublicKey) { - return peer.AddrInfo{}, errors.New("signing key does not match peer record") - } - - return peer.AddrInfo{ID: peerRecord.PeerID, Addrs: peerRecord.Addrs}, nil -} - -func newRegisterResponse(ttl int) *pb.Message_RegisterResponse { - ttl64 := int64(ttl) - r := new(pb.Message_RegisterResponse) - r.Status = pb.Message_OK - r.Ttl = ttl64 - return r -} - -func newRegisterResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_RegisterResponse { - r := new(pb.Message_RegisterResponse) - r.Status = status - r.StatusText = text - return r -} - -func newDiscoverResponse(regs []RegistrationRecord) (*pb.Message_DiscoverResponse, error) { - r := new(pb.Message_DiscoverResponse) - r.Status = pb.Message_OK - - rregs := make([]*pb.Message_Register, len(regs)) - for i, reg := range regs { - rreg := new(pb.Message_Register) - rns := reg.Ns - rreg.Ns = rns - rreg.SignedPeerRecord = reg.PeerEnvelope - rttl := int64(reg.Ttl) - rreg.Ttl = rttl - rregs[i] = rreg - } - - r.Registrations = rregs - - return r, nil -} - -func newDiscoverResponseError(status pb.Message_ResponseStatus, text string) *pb.Message_DiscoverResponse { - r := new(pb.Message_DiscoverResponse) - r.Status = status - r.StatusText = text - return r -} diff --git a/vendor/github.com/status-im/go-waku-rendezvous/storage.go b/vendor/github.com/status-im/go-waku-rendezvous/storage.go deleted file mode 100644 index 7195a03aa..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/storage.go +++ /dev/null @@ -1,161 +0,0 @@ -package rendezvous - -import ( - "bytes" - "crypto/rand" - "encoding/gob" - "time" - - "github.com/libp2p/go-libp2p-core/peer" -) - -const ( - RecordsPrefix byte = 1 + iota - - TopicBodyDelimiter = 0xff -) - -type Iterator interface { - Release() - Next() bool - Prev() bool - Value() []byte - Key() []byte - Seek([]byte) bool -} - -type DB interface { - Put([]byte, []byte) error - Delete([]byte) error - NewIterator([]byte) Iterator -} - -type RegistrationRecord struct { - PeerEnvelope []byte - Ns string - Ttl int - Deadline time.Time -} - -// TopicPart looks for TopicBodyDelimiter and returns topic prefix from the same key. -// It doesn't allocate memory for topic prefix. -func TopicPart(key []byte) []byte { - idx := bytes.IndexByte(key, TopicBodyDelimiter) - if idx == -1 { - return nil - } - return key[1:idx] // first byte is RecordsPrefix -} - -type RecordsKey []byte - -func NewRecordsKey(ns string, id peer.ID) RecordsKey { - key := make(RecordsKey, 2+len([]byte(ns))+len(id)) - key[0] = RecordsPrefix - copy(key[1:], []byte(ns)) - key[1+len([]byte(ns))] = TopicBodyDelimiter - copy(key[2+len([]byte(ns)):], id) - return key -} - -func (k RecordsKey) SamePrefix(prefix []byte) bool { - return bytes.Equal(k[:len(prefix)], prefix) -} - -func (k RecordsKey) String() string { - return string(k) -} - -// NewStorage creates instance of the storage. -func NewStorage(db DB) Storage { - return Storage{ - db: db, - } -} - -// Storage manages records. -type Storage struct { - db DB -} - -// Add stores record using specified topic. -func (s Storage) Add(ns string, id peer.ID, envelope []byte, ttl int, deadline time.Time) (string, error) { - key := NewRecordsKey(ns, id) - stored := RegistrationRecord{ - PeerEnvelope: envelope, - Ttl: ttl, - Ns: ns, - Deadline: deadline, - } - - var data bytes.Buffer - encoder := gob.NewEncoder(&data) - - err := encoder.Encode(stored) - if err != nil { - return "", err - } - return key.String(), s.db.Put(key, data.Bytes()) -} - -// RemoveBykey removes record from storage. -func (s *Storage) RemoveByKey(key string) error { - return s.db.Delete([]byte(key)) -} - -func (s *Storage) IterateAllKeys(iterator func(key RecordsKey, Deadline time.Time) error) error { - iter := s.db.NewIterator([]byte{RecordsPrefix}) - defer iter.Release() - - for iter.Next() { - var stored RegistrationRecord - data := bytes.NewBuffer(iter.Value()) - decoder := gob.NewDecoder(data) - if err := decoder.Decode(&stored); err != nil { - return err - } - if err := iterator(RecordsKey(iter.Key()), stored.Deadline); err != nil { - return err - } - } - return nil -} - -// GetRandom reads random records for specified topic up to specified limit. -func (s *Storage) GetRandom(ns string, limit int64) (rst []RegistrationRecord, err error) { - prefixlen := 1 + len([]byte(ns)) - key := make(RecordsKey, prefixlen+32) - key[0] = RecordsPrefix - copy(key[1:], []byte(ns)) - key[prefixlen] = TopicBodyDelimiter - prefixlen++ - - iter := s.db.NewIterator(key[:prefixlen]) - defer iter.Release() - uids := map[string]struct{}{} - // it might be too much cause we do crypto/rand.Read. requires profiling - for i := int64(0); i < limit*limit && len(rst) < int(limit); i++ { - if _, err := rand.Read(key[prefixlen:]); err != nil { - return nil, err - } - iter.Seek(key) - for _, f := range []func() bool{iter.Prev, iter.Next} { - if f() && key.SamePrefix(iter.Key()[:prefixlen]) { - var stored RegistrationRecord - data := bytes.NewBuffer(iter.Value()) - decoder := gob.NewDecoder(data) - if err = decoder.Decode(&stored); err != nil { - return nil, err - } - k := iter.Key() - if _, exist := uids[string(k)]; exist { - continue - } - uids[string(k)] = struct{}{} - rst = append(rst, stored) - break - } - } - } - return rst, nil -} diff --git a/vendor/github.com/status-im/go-waku-rendezvous/svc.go b/vendor/github.com/status-im/go-waku-rendezvous/svc.go deleted file mode 100644 index 12199d8a6..000000000 --- a/vendor/github.com/status-im/go-waku-rendezvous/svc.go +++ /dev/null @@ -1,247 +0,0 @@ -package rendezvous - -import ( - "sync" - "time" - - pb "github.com/status-im/go-waku-rendezvous/pb" - - ggio "github.com/gogo/protobuf/io" - - "github.com/libp2p/go-libp2p-core/host" - inet "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" -) - -const ( - MaxTTL = 20 // 20sec - networkDelay = 500 * time.Millisecond - cleanerPeriod = 2 * time.Second - MaxNamespaceLength = 256 - MaxPeerAddressLength = 2048 - MaxDiscoverLimit = int64(1000) -) - -type RendezvousService struct { - h host.Host - storage Storage - cleaner *Cleaner - wg sync.WaitGroup - quit chan struct{} -} - -func NewRendezvousService(host host.Host, storage Storage) *RendezvousService { - rz := &RendezvousService{ - storage: storage, - h: host, - cleaner: NewCleaner(), - } - - return rz -} - -func (rz *RendezvousService) Start() error { - rz.h.SetStreamHandler(RendezvousID_v001, rz.handleStream) - - if err := rz.startCleaner(); err != nil { - return err - } - // once server is restarted all cleaner info is lost. so we need to rebuild it - return rz.storage.IterateAllKeys(func(key RecordsKey, deadline time.Time) error { - if !rz.cleaner.Exist(key.String()) { - ns := TopicPart(key) - log.Debugf("active registration with", "ns", string(ns)) - } - rz.cleaner.Add(deadline, key.String()) - return nil - }) -} - -func (rz *RendezvousService) startCleaner() error { - rz.quit = make(chan struct{}) - rz.wg.Add(1) - go func() { - for { - select { - case <-time.After(cleanerPeriod): - rz.purgeOutdated() - case <-rz.quit: - rz.wg.Done() - return - } - } - }() - return nil -} - -// Stop closes listener and waits till all helper goroutines are stopped. -func (rz *RendezvousService) Stop() { - if rz.quit == nil { - return - } - select { - case <-rz.quit: - return - default: - } - close(rz.quit) - rz.wg.Wait() -} - -func (rz *RendezvousService) purgeOutdated() { - keys := rz.cleaner.PopSince(time.Now()) - log.Debug("removed records from cleaner", "deadlines", len(rz.cleaner.deadlines), "heap", len(rz.cleaner.heap), "lth", len(keys)) - for _, key := range keys { - topic := TopicPart([]byte(key)) - log.Debug("Removing record with", "topic", string(topic)) - if err := rz.storage.RemoveByKey(key); err != nil { - log.Error("error removing key from storage", "key", key, "error", err) - } - } -} - -func (rz *RendezvousService) handleStream(s inet.Stream) { - defer s.Reset() - - pid := s.Conn().RemotePeer() - log.Debugf("New stream from %s", pid.Pretty()) - - r := ggio.NewDelimitedReader(s, inet.MessageSizeMax) - w := ggio.NewDelimitedWriter(s) - - for { - var req pb.Message - var res pb.Message - - err := r.ReadMsg(&req) - if err != nil { - return - } - - t := req.GetType() - switch t { - case pb.Message_REGISTER: - r := rz.handleRegister(pid, req.GetRegister()) - res.Type = pb.Message_REGISTER_RESPONSE - res.RegisterResponse = r - err = w.WriteMsg(&res) - if err != nil { - log.Debugf("Error writing response: %s", err.Error()) - return - } - - case pb.Message_DISCOVER: - r := rz.handleDiscover(pid, req.GetDiscover()) - res.Type = pb.Message_DISCOVER_RESPONSE - res.DiscoverResponse = r - err = w.WriteMsg(&res) - if err != nil { - log.Debugf("Error writing response: %s", err.Error()) - return - } - - default: - log.Debugf("Unexpected message: %s", t.String()) - return - } - } -} - -func (rz *RendezvousService) handleRegister(p peer.ID, m *pb.Message_Register) *pb.Message_RegisterResponse { - ns := m.GetNs() - if ns == "" { - return newRegisterResponseError(pb.Message_E_INVALID_NAMESPACE, "unspecified namespace") - } - - if len(ns) > MaxNamespaceLength { - return newRegisterResponseError(pb.Message_E_INVALID_NAMESPACE, "namespace too long") - } - - mpi := m.GetSignedPeerRecord() - if mpi == nil { - return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "missing signed peer record") - } - - peerRecord, err := unmarshalSignedPeerRecord(mpi) - if err != nil { - return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "invalid peer record") - } - - if peerRecord.ID != p { - return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "peer id mismatch") - } - - if len(peerRecord.Addrs) == 0 { - return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "missing peer addresses") - } - - mlen := 0 - for _, maddr := range peerRecord.Addrs { - mlen += len(maddr.Bytes()) - } - if mlen > MaxPeerAddressLength { - return newRegisterResponseError(pb.Message_E_INVALID_PEER_INFO, "peer info too long") - } - - // Note: - // We don't validate the addresses, because they could include protocols we don't understand - // Perhaps we should though. - - mttl := m.GetTtl() - if mttl < 0 || mttl > MaxTTL { - return newRegisterResponseError(pb.Message_E_INVALID_TTL, "bad ttl") - } - - ttl := DefaultTTL - if mttl > 0 { - ttl = int(mttl) - } - - deadline := time.Now().Add(time.Duration(ttl)).Add(networkDelay) - - key, err := rz.storage.Add(ns, peerRecord.ID, mpi, ttl, deadline) - if err != nil { - return newRegisterResponseError(pb.Message_E_INTERNAL_ERROR, err.Error()) - } - - if !rz.cleaner.Exist(key) { - log.Debugf("active registration with", "ns", ns) - } - - log.Debugf("updating record in the cleaner", "deadline", deadline, "ns", ns) - rz.cleaner.Add(deadline, key) - - log.Infof("registered peer %s %s (%d)", p, ns, ttl) - - return newRegisterResponse(ttl) -} - -func (rz *RendezvousService) handleDiscover(p peer.ID, m *pb.Message_Discover) *pb.Message_DiscoverResponse { - ns := m.GetNs() - - if len(ns) > MaxNamespaceLength { - return newDiscoverResponseError(pb.Message_E_INVALID_NAMESPACE, "namespace too long") - } - - limit := MaxDiscoverLimit - mlimit := m.GetLimit() - if mlimit > 0 && mlimit < int64(limit) { - limit = mlimit - } - - records, err := rz.storage.GetRandom(ns, limit) - if err != nil { - log.Errorf("Error in query: %s", err.Error()) - return newDiscoverResponseError(pb.Message_E_INTERNAL_ERROR, "database error") - } - - log.Infof("discover query: %s %s -> %d", p, ns, len(records)) - - response, err := newDiscoverResponse(records) - if err != nil { - log.Errorf("Error in response: %s", err.Error()) - return newDiscoverResponseError(pb.Message_E_INTERNAL_ERROR, "error building response") - } - - return response -} diff --git a/vendor/github.com/status-im/go-waku/logging/logging.go b/vendor/github.com/status-im/go-waku/logging/logging.go index 6e6575009..cbd0b3157 100644 --- a/vendor/github.com/status-im/go-waku/logging/logging.go +++ b/vendor/github.com/status-im/go-waku/logging/logging.go @@ -4,22 +4,47 @@ // implementation purposely does as little as possible at field creation time, // and postpones any transformation to output time by relying on the generic // zap types like zap.Stringer, zap.Array, zap.Object -// package logging import ( + "encoding/hex" "net" "time" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/p2p/enode" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" "github.com/multiformats/go-multiaddr" "github.com/status-im/go-waku/waku/v2/protocol/pb" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) +// List of []byte +type byteArr [][]byte + +// HexArray creates a field with an array of bytes that will be shown as a hexadecimal string in logs +func HexArray(key string, byteVal ...[]byte) zapcore.Field { + return zap.Array(key, byteArr(byteVal)) +} + +func (bArr byteArr) MarshalLogArray(encoder zapcore.ArrayEncoder) error { + for _, b := range bArr { + encoder.AppendString(hex.EncodeToString(b)) + } + return nil +} + +type hexByte []byte + +func HexString(key string, byteVal []byte) zapcore.Field { + return zap.Stringer(key, hexByte(byteVal)) +} + +func (h hexByte) String() string { + return hex.EncodeToString(h) +} + // List of multiaddrs type multiaddrs []multiaddr.Multiaddr diff --git a/vendor/github.com/status-im/go-waku/waku/persistence/migrations/migrate.go b/vendor/github.com/status-im/go-waku/waku/persistence/migrations/migrate.go index b800b1867..a1f00154d 100644 --- a/vendor/github.com/status-im/go-waku/waku/persistence/migrations/migrate.go +++ b/vendor/github.com/status-im/go-waku/waku/persistence/migrations/migrate.go @@ -1,5 +1,5 @@ -//go:build gowaku_run_migrations -// +build gowaku_run_migrations +//go:build !gowaku_skip_migrations +// +build !gowaku_skip_migrations package migrations diff --git a/vendor/github.com/status-im/go-waku/waku/persistence/migrations/no_migrations.go b/vendor/github.com/status-im/go-waku/waku/persistence/migrations/no_migrations.go index 66d087b6c..ae2297f3f 100644 --- a/vendor/github.com/status-im/go-waku/waku/persistence/migrations/no_migrations.go +++ b/vendor/github.com/status-im/go-waku/waku/persistence/migrations/no_migrations.go @@ -1,5 +1,5 @@ -//go:build !gowaku_run_migrations -// +build !gowaku_run_migrations +//go:build gowaku_skip_migrations +// +build gowaku_skip_migrations package migrations diff --git a/vendor/github.com/status-im/go-waku/waku/persistence/rendezvous.go b/vendor/github.com/status-im/go-waku/waku/persistence/rendezvous.go deleted file mode 100644 index 18c350577..000000000 --- a/vendor/github.com/status-im/go-waku/waku/persistence/rendezvous.go +++ /dev/null @@ -1,40 +0,0 @@ -package persistence - -import ( - rendezvous "github.com/status-im/go-waku-rendezvous" - "github.com/syndtr/goleveldb/leveldb" - "github.com/syndtr/goleveldb/leveldb/opt" - "github.com/syndtr/goleveldb/leveldb/util" -) - -// RendezVousLevelDB is a struct used to hold a reference to a LevelDB database -type RendezVousLevelDB struct { - db *leveldb.DB -} - -// NewRendezVousLevelDB opens a LevelDB database to be used for rendezvous protocol -func NewRendezVousLevelDB(dBPath string) (*RendezVousLevelDB, error) { - db, err := leveldb.OpenFile(dBPath, &opt.Options{OpenFilesCacheCapacity: 3}) - - if err != nil { - return nil, err - } - - return &RendezVousLevelDB{db}, nil -} - -// Delete removes a key from the database -func (r *RendezVousLevelDB) Delete(key []byte) error { - return r.db.Delete(key, nil) -} - -// Put inserts or updates a key in the database -func (r *RendezVousLevelDB) Put(key []byte, value []byte) error { - return r.db.Put(key, value, nil) -} - -// NewIterator returns an interator that can be used to iterate over all -// the records contained in the DB -func (r *RendezVousLevelDB) NewIterator(prefix []byte) rendezvous.Iterator { - return r.db.NewIterator(util.BytesPrefix(prefix), nil) -} diff --git a/vendor/github.com/status-im/go-waku/waku/v2/discv5/discover.go b/vendor/github.com/status-im/go-waku/waku/v2/discv5/discover.go index 9912bc722..6baf82115 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/discv5/discover.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/discv5/discover.go @@ -11,12 +11,12 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/nat" - "github.com/libp2p/go-libp2p-core/discovery" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/status-im/go-discover/discover" + "github.com/libp2p/go-libp2p/core/discovery" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" "github.com/status-im/go-waku/logging" "github.com/status-im/go-waku/waku/v2/utils" + "github.com/waku-org/go-discover/discover" "go.uber.org/zap" ) @@ -61,6 +61,8 @@ type discV5Parameters struct { type DiscoveryV5Option func(*discV5Parameters) +var protocolID = [6]byte{'d', '5', 'w', 'a', 'k', 'u'} + func WithAutoUpdate(autoUpdate bool) DiscoveryV5Option { return func(params *discV5Parameters) { params.autoUpdate = autoUpdate @@ -124,7 +126,7 @@ func NewDiscoveryV5(host host.Host, priv *ecdsa.PrivateKey, localnode *enode.Loc return evaluateNode(&n) }, V5Config: discover.V5Config{ - ProtocolID: [6]byte{'d', '5', 'w', 'a', 'k', 'u'}, + ProtocolID: &protocolID, }, }, udpAddr: &net.UDPAddr{ diff --git a/vendor/github.com/status-im/go-waku/waku/v2/node/connectedness.go b/vendor/github.com/status-im/go-waku/waku/v2/node/connectedness.go index 6c9c74d69..aa4842b65 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/node/connectedness.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/node/connectedness.go @@ -3,10 +3,10 @@ package node import ( "context" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" "github.com/status-im/go-waku/logging" "github.com/status-im/go-waku/waku/v2/metrics" "github.com/status-im/go-waku/waku/v2/protocol/filter" @@ -49,11 +49,11 @@ func NewConnectionNotifier(ctx context.Context, h host.Host, log *zap.Logger) Co } // Listen is called when network starts listening on an addr -func (c ConnectionNotifier) Listen(n network.Network, m ma.Multiaddr) { +func (c ConnectionNotifier) Listen(n network.Network, m multiaddr.Multiaddr) { } // ListenClose is called when network stops listening on an address -func (c ConnectionNotifier) ListenClose(n network.Network, m ma.Multiaddr) { +func (c ConnectionNotifier) ListenClose(n network.Network, m multiaddr.Multiaddr) { } // Connected is called when a connection is opened diff --git a/vendor/github.com/status-im/go-waku/waku/v2/node/keepalive.go b/vendor/github.com/status-im/go-waku/waku/v2/node/keepalive.go index 52fe0bb47..5e01c8229 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/node/keepalive.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/node/keepalive.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/protocol/ping" "github.com/status-im/go-waku/logging" "go.uber.org/zap" diff --git a/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2.go b/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2.go index f85dd5c27..0165e0b1e 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2.go @@ -8,22 +8,22 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/libp2p/go-libp2p" "go.uber.org/zap" - "github.com/libp2p/go-libp2p-core/event" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-core/peerstore" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/event" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/libp2p/go-libp2p/core/peerstore" ws "github.com/libp2p/go-libp2p/p2p/transport/websocket" ma "github.com/multiformats/go-multiaddr" "go.opencensus.io/stats" - rendezvous "github.com/status-im/go-waku-rendezvous" "github.com/status-im/go-waku/logging" "github.com/status-im/go-waku/waku/try" v2 "github.com/status-im/go-waku/waku/v2" @@ -49,13 +49,14 @@ type Peer struct { type storeFactory func(w *WakuNode) store.Store type MembershipKeyPair = struct { - IDKey [32]byte - IDCommitment [32]byte + IDKey [32]byte `json:"idKey"` + IDCommitment [32]byte `json:"idCommitment"` } type RLNRelay interface { - MembershipKeyPair() MembershipKeyPair + MembershipKeyPair() *MembershipKeyPair MembershipIndex() uint + MembershipContractAddress() common.Address AppendRLNProof(msg *pb.WakuMessage, senderEpochTime time.Time) error Stop() } @@ -65,14 +66,13 @@ type WakuNode struct { opts *WakuNodeParameters log *zap.Logger - relay *relay.WakuRelay - filter *filter.WakuFilter - lightPush *lightpush.WakuLightPush - rendezvous *rendezvous.RendezvousService - store store.Store - swap *swap.WakuSwap - rlnRelay RLNRelay - wakuFlag utils.WakuEnrBitfield + relay *relay.WakuRelay + filter *filter.WakuFilter + lightPush *lightpush.WakuLightPush + store store.Store + swap *swap.WakuSwap + rlnRelay RLNRelay + wakuFlag utils.WakuEnrBitfield localNode *enode.LocalNode @@ -279,11 +279,6 @@ func (w *WakuNode) Start() error { w.filter = filter } - if w.opts.enableRendezvous { - rendezvous := rendezvous.NewRendezvousDiscovery(w.host) - w.opts.wOpts = append(w.opts.wOpts, pubsub.WithDiscovery(rendezvous, w.opts.rendezvousOpts...)) - } - err := w.setupENR(w.ListenAddresses()) if err != nil { return err @@ -319,13 +314,6 @@ func (w *WakuNode) Start() error { } } - if w.opts.enableRendezvousServer { - err := w.mountRendezvous() - if err != nil { - return err - } - } - // Subscribe store to topic if w.opts.storeMsgs { w.log.Info("Subscribing store to broadcaster") @@ -353,10 +341,6 @@ func (w *WakuNode) Stop() { defer w.identificationEventSub.Close() defer w.addressChangesSub.Close() - if w.rendezvous != nil { - w.rendezvous.Stop() - } - if w.filter != nil { w.filter.Stop() } @@ -434,7 +418,7 @@ func (w *WakuNode) Publish(ctx context.Context, msg *pb.WakuMessage) error { return errors.New("cannot publish message, relay and lightpush are disabled") } - hash, _ := msg.Hash() + hash, _, _ := msg.Hash() err := try.Do(func(attempt int) (bool, error) { var err error if !w.relay.EnoughPeersToPublish() { @@ -490,17 +474,6 @@ func (w *WakuNode) mountDiscV5() error { return err } -func (w *WakuNode) mountRendezvous() error { - w.rendezvous = rendezvous.NewRendezvousService(w.host, w.opts.rendevousStorage) - - if err := w.rendezvous.Start(); err != nil { - return err - } - - w.log.Info("Rendezvous service started") - return nil -} - func (w *WakuNode) startStore() { w.store.Start(w.ctx) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2_rln.go b/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2_rln.go index fd15fee8d..046b5b531 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2_rln.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/node/wakunode2_rln.go @@ -9,7 +9,7 @@ import ( "errors" "github.com/status-im/go-waku/waku/v2/protocol/rln" - r "github.com/status-im/go-zerokit-rln/rln" + r "github.com/waku-org/go-zerokit-rln/rln" "go.uber.org/zap" ) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions.go b/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions.go index 26ed10343..5362d39d7 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions.go @@ -12,9 +12,9 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p-core/crypto" pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/config" + "github.com/libp2p/go-libp2p/core/crypto" basichost "github.com/libp2p/go-libp2p/p2p/host/basic" "github.com/libp2p/go-libp2p/p2p/muxer/mplex" "github.com/libp2p/go-libp2p/p2p/muxer/yamux" @@ -23,7 +23,6 @@ import ( "github.com/libp2p/go-libp2p/p2p/transport/tcp" "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr/net" - rendezvous "github.com/status-im/go-waku-rendezvous" "github.com/status-im/go-waku/waku/v2/protocol/filter" "github.com/status-im/go-waku/waku/v2/protocol/pb" "github.com/status-im/go-waku/waku/v2/protocol/store" @@ -31,8 +30,8 @@ import ( "go.uber.org/zap" ) -// Default clientId -const clientId string = "Go Waku v2 node" +// Default userAgent +const userAgent string = "go-waku" // Default minRelayPeersToPublish const defaultMinRelayPeersToPublish = 0 @@ -72,11 +71,6 @@ type WakuNodeParameters struct { swapDisconnectThreshold int swapPaymentThreshold int - enableRendezvous bool - enableRendezvousServer bool - rendevousStorage rendezvous.Storage - rendezvousOpts []pubsub.DiscoverOpt - enableDiscV5 bool udpPort int discV5bootnodes []*enode.Node @@ -283,26 +277,6 @@ func WithDiscoveryV5(udpPort int, bootnodes []*enode.Node, autoUpdate bool, disc } } -// WithRendezvous is a WakuOption used to enable go-waku-rendezvous discovery. -// It accepts an optional list of DiscoveryOpt options -func WithRendezvous(discoverOpts ...pubsub.DiscoverOpt) WakuNodeOption { - return func(params *WakuNodeParameters) error { - params.enableRendezvous = true - params.rendezvousOpts = discoverOpts - return nil - } -} - -// WithRendezvousServer is a WakuOption used to set the node as a rendezvous -// point, using an specific storage for the peer information -func WithRendezvousServer(storage rendezvous.Storage) WakuNodeOption { - return func(params *WakuNodeParameters) error { - params.enableRendezvousServer = true - params.rendevousStorage = storage - return nil - } -} - // WithWakuFilter enables the Waku V2 Filter protocol. This WakuNodeOption // accepts a list of WakuFilter gossipsub options to setup the protocol func WithWakuFilter(fullNode bool, filterOpts ...filter.Option) WakuNodeOption { @@ -431,7 +405,8 @@ var DefaultLibP2POptions = []libp2p.Option{ libp2p.ChainOptions( libp2p.Transport(tcp.NewTCPTransport), libp2p.Transport(quic.NewTransport), - ), libp2p.UserAgent(clientId), + ), + libp2p.UserAgent(userAgent), libp2p.ChainOptions( libp2p.Muxer("/yamux/1.0.0", yamux.DefaultTransport), libp2p.Muxer("/mplex/6.7.0", mplex.DefaultTransport), diff --git a/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions_rln.go b/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions_rln.go index 805a9e8b4..bb3f9403d 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions_rln.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/node/wakuoptions_rln.go @@ -8,7 +8,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/status-im/go-waku/waku/v2/protocol/rln" - r "github.com/status-im/go-zerokit-rln/rln" + r "github.com/waku-org/go-zerokit-rln/rln" ) // WithStaticRLNRelay enables the Waku V2 RLN protocol in offchain mode @@ -25,21 +25,29 @@ func WithStaticRLNRelay(pubsubTopic string, contentTopic string, memberIndex r.M } } +type MembershipCredentials struct { + Contract common.Address `json:"contract"` + Keypair *r.MembershipKeyPair `json:"membershipKeyPair"` + Index r.MembershipIndex `json:"rlnIndex"` +} + // WithStaticRLNRelay enables the Waku V2 RLN protocol in onchain mode. // Requires the `gowaku_rln` build constrain (or the env variable RLN=true if building go-waku) -func WithDynamicRLNRelay(pubsubTopic string, contentTopic string, memberIndex r.MembershipIndex, idKey *r.IDKey, idCommitment *r.IDCommitment, spamHandler rln.SpamHandler, ethClientAddress string, ethPrivateKey *ecdsa.PrivateKey, membershipContractAddress common.Address, registrationHandler rln.RegistrationHandler) WakuNodeOption { +func WithDynamicRLNRelay(pubsubTopic string, contentTopic string, membershipCredentials MembershipCredentials, spamHandler rln.SpamHandler, ethClientAddress string, ethPrivateKey *ecdsa.PrivateKey, registrationHandler rln.RegistrationHandler) WakuNodeOption { return func(params *WakuNodeParameters) error { params.enableRLN = true params.rlnRelayDynamic = true - params.rlnRelayMemIndex = memberIndex - params.rlnRelayIDKey = idKey - params.rlnRelayIDCommitment = idCommitment + params.rlnRelayMemIndex = membershipCredentials.Index + if membershipCredentials.Keypair != nil { + params.rlnRelayIDKey = &membershipCredentials.Keypair.IDKey + params.rlnRelayIDCommitment = &membershipCredentials.Keypair.IDCommitment + } params.rlnRelayPubsubTopic = pubsubTopic params.rlnRelayContentTopic = contentTopic params.rlnSpamHandler = spamHandler params.rlnETHClientAddress = ethClientAddress params.rlnETHPrivateKey = ethPrivateKey - params.rlnMembershipContractAddress = membershipContractAddress + params.rlnMembershipContractAddress = membershipCredentials.Contract params.rlnRegistrationHandler = registrationHandler return nil } diff --git a/vendor/github.com/status-im/go-waku/waku/v2/noise/handshake.go b/vendor/github.com/status-im/go-waku/waku/v2/noise/handshake.go index cbd3c6d2f..795a6b67e 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/noise/handshake.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/noise/handshake.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" - n "github.com/flynn/noise" + n "github.com/waku-org/noise" ) // WakuNoiseProtocolID indicates the protocol ID defined according to https://rfc.vac.dev/spec/35/#specification @@ -116,6 +116,7 @@ func (hs *Handshake) Step(readPayloadV2 *PayloadV2, transportMessage []byte) (*H var cs2 *n.CipherState var err error var msg []byte + var noisePubKeys [][]byte result := HandshakeStepResult{} @@ -128,8 +129,7 @@ func (hs *Handshake) Step(readPayloadV2 *PayloadV2, transportMessage []byte) (*H return nil, err } - var noisePubKeys [][]byte - msg, cs1, cs2, err = hs.state.WriteMessageAndGetPK(hs.hsBuff, &noisePubKeys, payload) + msg, noisePubKeys, cs1, cs2, err = hs.state.WriteMessageAndGetPK(hs.hsBuff, [][]byte{}, payload) if err != nil { return nil, err } diff --git a/vendor/github.com/status-im/go-waku/waku/v2/noise/patterns.go b/vendor/github.com/status-im/go-waku/waku/v2/noise/patterns.go index 1b454b1d3..d1ab15a65 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/noise/patterns.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/noise/patterns.go @@ -1,17 +1,18 @@ package noise import ( - n "github.com/flynn/noise" + n "github.com/waku-org/noise" ) /* - K1K1: - -> s - <- s - ... - -> e - <- e, ee, es - -> se +K1K1: + + -> s + <- s + ... + -> e + <- e, ee, es + -> se */ var HandshakeK1K1 = n.HandshakePattern{ Name: "K1K1", @@ -25,12 +26,13 @@ var HandshakeK1K1 = n.HandshakePattern{ } /* - XK1: - <- s - ... - -> e - <- e, ee, es - -> s, se +XK1: + + <- s + ... + -> e + <- e, ee, es + -> s, se */ var HandshakeXK1 = n.HandshakePattern{ Name: "XK1", @@ -44,9 +46,10 @@ var HandshakeXK1 = n.HandshakePattern{ /* XX: - -> e - <- e, ee, s, es - -> s, se + + -> e + <- e, ee, s, es + -> s, se */ var HandshakeXX = n.HandshakePattern{ Name: "XX", @@ -58,10 +61,11 @@ var HandshakeXX = n.HandshakePattern{ } /* - XXpsk0: - -> psk, e - <- e, ee, s, es - -> s, se +XXpsk0: + + -> psk, e + <- e, ee, s, es + -> s, se */ var HandshakeXXpsk0 = n.HandshakePattern{ Name: "XXpsk0", diff --git a/vendor/github.com/status-im/go-waku/waku/v2/noise/payload.go b/vendor/github.com/status-im/go-waku/waku/v2/noise/payload.go index 23d7065dd..40bc0438f 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/noise/payload.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/noise/payload.go @@ -6,7 +6,7 @@ import ( "encoding/binary" "errors" - n "github.com/flynn/noise" + n "github.com/waku-org/noise" ) const MaxUint8 = 1<<8 - 1 diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/envelope.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/envelope.go index c292b9195..820f93481 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/envelope.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/envelope.go @@ -20,13 +20,12 @@ type Envelope struct { // It's used as a way to know to which Pubsub topic belongs a WakuMessage // as well as generating a hash based on the bytes that compose the message func NewEnvelope(msg *pb.WakuMessage, receiverTime int64, pubSubTopic string) *Envelope { - data, _ := msg.Marshal() + messageHash, dataLen, _ := msg.Hash() hash := sha256.Sum256(append([]byte(msg.ContentTopic), msg.Payload...)) - return &Envelope{ msg: msg, - size: len(data), - hash: pb.Hash(data), + size: dataLen, + hash: messageHash, index: &pb.Index{ Digest: hash[:], ReceiverTime: receiverTime, diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/filter_subscribers.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/filter_subscribers.go index 2095409e6..2ca7422d4 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/filter_subscribers.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/filter_subscribers.go @@ -4,7 +4,7 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/peer" "github.com/status-im/go-waku/waku/v2/protocol/pb" ) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter.go index c98bbee09..00488b942 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter.go @@ -7,10 +7,10 @@ import ( "math" "sync" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - libp2pProtocol "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + libp2pProtocol "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-msgio/protoio" "github.com/status-im/go-waku/logging" "github.com/status-im/go-waku/waku/v2/metrics" diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter_option.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter_option.go index 3c870a18e..df4eeba96 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter_option.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/filter/waku_filter_option.go @@ -4,8 +4,8 @@ import ( "context" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" "github.com/status-im/go-waku/waku/v2/utils" "go.uber.org/zap" ) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush.go index 5f43578eb..70b5fc299 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush.go @@ -6,9 +6,9 @@ import ( "errors" "math" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - libp2pProtocol "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + libp2pProtocol "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-msgio/protoio" "github.com/status-im/go-waku/logging" "github.com/status-im/go-waku/waku/v2/metrics" @@ -49,7 +49,7 @@ func NewWakuLightPush(ctx context.Context, h host.Host, relay *relay.WakuRelay, // Start inits the lighpush protocol func (wakuLP *WakuLightPush) Start() error { - if wakuLP.IsClientOnly() { + if wakuLP.relayIsNotAvailable() { return errors.New("relay is required, without it, it is only a client and cannot be started") } @@ -60,8 +60,8 @@ func (wakuLP *WakuLightPush) Start() error { return nil } -// IsClientOnly determines if this node supports relaying messages for other lightpush clients -func (wakuLp *WakuLightPush) IsClientOnly() bool { +// relayIsNotAvailable determines if this node supports relaying messages for other lightpush clients +func (wakuLp *WakuLightPush) relayIsNotAvailable() bool { return wakuLp.relay == nil } @@ -85,7 +85,7 @@ func (wakuLP *WakuLightPush) onRequest(s network.Stream) { if requestPushRPC.Query != nil { logger.Info("push request") response := new(pb.PushResponse) - if !wakuLP.IsClientOnly() { + if !wakuLP.relayIsNotAvailable() { pubSubTopic := requestPushRPC.Query.PubsubTopic message := requestPushRPC.Query.Message @@ -203,8 +203,10 @@ func (wakuLP *WakuLightPush) IsStarted() bool { // Stop unmounts the lightpush protocol func (wakuLP *WakuLightPush) Stop() { - wakuLP.h.RemoveStreamHandler(LightPushID_v20beta1) - wakuLP.started = false + if wakuLP.started { + wakuLP.h.RemoveStreamHandler(LightPushID_v20beta1) + wakuLP.started = false + } } // PublishToTopic is used to broadcast a WakuMessage to a pubsub topic via lightpush protocol @@ -223,7 +225,8 @@ func (wakuLP *WakuLightPush) PublishToTopic(ctx context.Context, message *pb.Wak } if response.IsSuccess { - hash, _ := message.Hash() + hash, _, _ := message.Hash() + wakuLP.log.Info("received", logging.HexString("messageID", hash)) return hash, nil } else { return nil, errors.New(response.Info) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush_option.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush_option.go index 4b3107d41..edfcd6491 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush_option.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/lightpush/waku_lightpush_option.go @@ -3,8 +3,8 @@ package lightpush import ( "context" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" "github.com/status-im/go-waku/waku/v2/protocol" "github.com/status-im/go-waku/waku/v2/utils" "go.uber.org/zap" diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/pb/utils.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/pb/utils.go index 80f392a02..51c1cef86 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/pb/utils.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/pb/utils.go @@ -7,13 +7,13 @@ import ( ) // Hash calculates the hash of a waku message -func (msg *WakuMessage) Hash() ([]byte, error) { +func (msg *WakuMessage) Hash() ([]byte, int, error) { out, err := proto.Marshal(msg) if err != nil { - return nil, err + return nil, 0, err } - return Hash(out), nil + return Hash(out), len(out), nil } // Hash calculates a hash from a byte slice using sha2-256 for the hashing algorithm diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/relay/waku_relay.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/relay/waku_relay.go index ef54d647a..4a0916e75 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/relay/waku_relay.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/relay/waku_relay.go @@ -3,19 +3,21 @@ package relay import ( "context" "crypto/sha256" + "encoding/hex" "errors" "fmt" "sync" proto "github.com/golang/protobuf/proto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/protocol" "go.opencensus.io/stats" "go.opencensus.io/tag" "go.uber.org/zap" pubsub "github.com/libp2p/go-libp2p-pubsub" pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb" + "github.com/status-im/go-waku/logging" v2 "github.com/status-im/go-waku/waku/v2" "github.com/status-im/go-waku/waku/v2/metrics" waku_proto "github.com/status-im/go-waku/waku/v2/protocol" @@ -184,6 +186,8 @@ func (w *WakuRelay) PublishToTopic(ctx context.Context, message *pb.WakuMessage, hash := pb.Hash(out) + w.log.Info("published", zap.String("messageID", hex.EncodeToString(hash))) + return hash, nil } @@ -341,6 +345,8 @@ func (w *WakuRelay) subscribeToTopic(t string, subscription *Subscription, sub * envelope := waku_proto.NewEnvelope(wakuMessage, utils.GetUnixEpoch(), string(t)) + w.log.Info("received", logging.HexString("messageID", envelope.Hash())) + if w.bcaster != nil { w.bcaster.Submit(envelope) } diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/rln_relay_builder.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/rln_relay_builder.go index d5620521f..164ebf9aa 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/rln_relay_builder.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/rln_relay_builder.go @@ -7,7 +7,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/status-im/go-waku/waku/v2/protocol/relay" - r "github.com/status-im/go-zerokit-rln/rln" + r "github.com/waku-org/go-zerokit-rln/rln" "go.uber.org/zap" ) @@ -36,17 +36,10 @@ func RlnRelayStatic( return nil, err } - // add members to the Merkle tree - for _, member := range group { - if err := rlnInstance.InsertMember(member); err != nil { - return nil, err - } - } - // create the WakuRLNRelay rlnPeer := &WakuRLNRelay{ ctx: ctx, - membershipKeyPair: memKeyPair, + membershipKeyPair: &memKeyPair, membershipIndex: memIndex, RLN: rlnInstance, pubsubTopic: pubsubTopic, @@ -55,6 +48,20 @@ func RlnRelayStatic( nullifierLog: make(map[r.Epoch][]r.ProofMetadata), } + root, err := rlnPeer.RLN.GetMerkleRoot() + if err != nil { + return nil, err + } + + rlnPeer.validMerkleRoots = append(rlnPeer.validMerkleRoots, root) + + // add members to the Merkle tree + for _, member := range group { + if err := rlnPeer.insertMember(member); err != nil { + return nil, err + } + } + // adds a topic validator for the supplied pubsub topic at the relay protocol // messages published on this pubsub topic will be relayed upon a successful validation, otherwise they will be dropped // the topic validator checks for the correct non-spamming proof of the message @@ -106,15 +113,22 @@ func RlnRelayDynamic( registrationHandler: registrationHandler, } + root, err := rlnPeer.RLN.GetMerkleRoot() + if err != nil { + return nil, err + } + + rlnPeer.validMerkleRoots = append(rlnPeer.validMerkleRoots, root) + // prepare rln membership key pair - if memKeyPair == nil { + if memKeyPair == nil && ethAccountPrivateKey != nil { log.Debug("no rln-relay key is provided, generating one") memKeyPair, err = rlnInstance.MembershipKeyGen() if err != nil { return nil, err } - rlnPeer.membershipKeyPair = *memKeyPair + rlnPeer.membershipKeyPair = memKeyPair // register the rln-relay peer to the membership contract membershipIndex, err := rlnPeer.Register(ctx) @@ -125,14 +139,12 @@ func RlnRelayDynamic( rlnPeer.membershipIndex = *membershipIndex log.Info("registered peer into the membership contract") - } else { - rlnPeer.membershipKeyPair = *memKeyPair + } else if memKeyPair != nil { + rlnPeer.membershipKeyPair = memKeyPair } handler := func(pubkey r.IDCommitment, index r.MembershipIndex) error { - log.Debug("a new key is added", zap.Binary("pubkey", pubkey[:])) - // assuming all the members arrive in order - return rlnInstance.InsertMember(pubkey) + return rlnPeer.insertMember(pubkey) } errChan := make(chan error) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/waku_rln_relay.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/waku_rln_relay.go index 6d39b6392..0ad88214f 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/waku_rln_relay.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/waku_rln_relay.go @@ -6,18 +6,19 @@ import ( "crypto/ecdsa" "errors" "math" + "sync" "time" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" proto "github.com/golang/protobuf/proto" - "github.com/libp2p/go-libp2p-core/peer" pubsub "github.com/libp2p/go-libp2p-pubsub" + "github.com/libp2p/go-libp2p/core/peer" "github.com/status-im/go-waku/waku/v2/protocol/pb" "github.com/status-im/go-waku/waku/v2/protocol/relay" "github.com/status-im/go-waku/waku/v2/utils" - r "github.com/status-im/go-zerokit-rln/rln" + r "github.com/waku-org/go-zerokit-rln/rln" "go.uber.org/zap" ) @@ -29,10 +30,12 @@ const MAX_EPOCH_GAP = int64(MAX_CLOCK_GAP_SECONDS / r.EPOCH_UNIT_SECONDS) type RegistrationHandler = func(tx *types.Transaction) +const AcceptableRootWindowSize = 5 + type WakuRLNRelay struct { ctx context.Context - membershipKeyPair r.MembershipKeyPair + membershipKeyPair *r.MembershipKeyPair // membershipIndex denotes the index of a leaf in the Merkle tree // that contains the pk of the current peer @@ -48,10 +51,15 @@ type WakuRLNRelay struct { RLN *r.RLN // pubsubTopic is the topic for which rln relay is mounted - pubsubTopic string - contentTopic string + pubsubTopic string + contentTopic string + lastIndexLoaded r.MembershipIndex + + validMerkleRoots []r.MerkleNode + // the log of nullifiers and Shamir shares of the past messages grouped per epoch - nullifierLog map[r.Epoch][]r.ProofMetadata + nullifierLogLock sync.RWMutex + nullifierLog map[r.Epoch][]r.ProofMetadata registrationHandler RegistrationHandler log *zap.Logger @@ -112,7 +120,9 @@ func (rln *WakuRLNRelay) HasDuplicate(msg *pb.WakuMessage) (bool, error) { ShareY: msgProof.ShareY, } + rln.nullifierLogLock.RLock() proofs, ok := rln.nullifierLog[msgProof.Epoch] + rln.nullifierLogLock.RUnlock() // check if the epoch exists if !ok { @@ -154,6 +164,8 @@ func (rln *WakuRLNRelay) updateLog(msg *pb.WakuMessage) (bool, error) { ShareY: msgProof.ShareY, } + rln.nullifierLogLock.Lock() + defer rln.nullifierLogLock.Unlock() proofs, ok := rln.nullifierLog[msgProof.Epoch] // check if the epoch exists @@ -183,7 +195,6 @@ func (rln *WakuRLNRelay) ValidateMessage(msg *pb.WakuMessage, optionalTime *time // the `msg` does not violate the rate limit // `timeOption` indicates Unix epoch time (fractional part holds sub-seconds) // if `timeOption` is supplied, then the current epoch is calculated based on that - if msg == nil { return MessageValidationResult_Unknown, errors.New("nil message") } @@ -207,7 +218,7 @@ func (rln *WakuRLNRelay) ValidateMessage(msg *pb.WakuMessage, optionalTime *time // calculate the gaps and validate the epoch gap := r.Diff(epoch, msgProof.Epoch) - if int64(math.Abs(float64(gap))) >= MAX_EPOCH_GAP { + if int64(math.Abs(float64(gap))) > MAX_EPOCH_GAP { // message's epoch is too old or too ahead // accept messages whose epoch is within +-MAX_EPOCH_GAP from the current epoch rln.log.Debug("invalid message: epoch gap exceeds a threshold", zap.Int64("gap", gap)) @@ -217,9 +228,18 @@ func (rln *WakuRLNRelay) ValidateMessage(msg *pb.WakuMessage, optionalTime *time // verify the proof contentTopicBytes := []byte(msg.ContentTopic) input := append(msg.Payload, contentTopicBytes...) - if !rln.RLN.Verify(input, *msgProof) { + + // TODO: set window of roots + roots := [][32]byte{} + valid, err := rln.RLN.VerifyWithRoots(input, *msgProof, roots) + if err != nil { + rln.log.Debug("could not verify proof", zap.Error(err)) + return MessageValidationResult_Invalid, nil + } + + if !valid { // invalid proof - rln.log.Debug("invalid message: invalid proof") + rln.log.Debug("Invalid proof") return MessageValidationResult_Invalid, nil } @@ -256,9 +276,13 @@ func (rln *WakuRLNRelay) AppendRLNProof(msg *pb.WakuMessage, senderEpochTime tim return errors.New("nil message") } + if rln.membershipKeyPair == nil { + return errors.New("No keypair setup") + } + input := toRLNSignal(msg) - proof, err := rln.RLN.GenerateProof(input, rln.membershipKeyPair, rln.membershipIndex, r.CalcEpoch(senderEpochTime)) + proof, err := rln.RLN.GenerateProof(input, *rln.membershipKeyPair, rln.membershipIndex, r.CalcEpoch(senderEpochTime)) if err != nil { return err } @@ -276,7 +300,7 @@ func (rln *WakuRLNRelay) AppendRLNProof(msg *pb.WakuMessage, senderEpochTime tim return nil } -func (r *WakuRLNRelay) MembershipKeyPair() r.MembershipKeyPair { +func (r *WakuRLNRelay) MembershipKeyPair() *r.MembershipKeyPair { return r.membershipKeyPair } @@ -284,6 +308,29 @@ func (r *WakuRLNRelay) MembershipIndex() r.MembershipIndex { return r.membershipIndex } +func (r *WakuRLNRelay) MembershipContractAddress() common.Address { + return r.membershipContractAddress +} + +func (r *WakuRLNRelay) insertMember(pubkey [32]byte) error { + r.log.Debug("a new key is added", zap.Binary("pubkey", pubkey[:])) + // assuming all the members arrive in order + err := r.RLN.InsertMember(pubkey) + if err == nil { + newRoot, err := r.RLN.GetMerkleRoot() + if err != nil { + r.log.Error("inserting member into merkletree", zap.Error(err)) + return err + } + r.validMerkleRoots = append(r.validMerkleRoots, newRoot) + if len(r.validMerkleRoots) > AcceptableRootWindowSize { + r.validMerkleRoots = r.validMerkleRoots[1:] + } + } + + return err +} + type SpamHandler = func(message *pb.WakuMessage) error // this function sets a validator for the waku messages published on the supplied pubsubTopic and contentTopic diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/web3.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/web3.go index 06bba8ccf..fa04bdc32 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/web3.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/rln/web3.go @@ -5,14 +5,16 @@ import ( "crypto/ecdsa" "errors" "math/big" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/rpc" "github.com/status-im/go-waku/waku/v2/protocol/rln/contracts" - r "github.com/status-im/go-zerokit-rln/rln" + r "github.com/waku-org/go-zerokit-rln/rln" "go.uber.org/zap" ) @@ -105,7 +107,7 @@ func (rln *WakuRLNRelay) Register(ctx context.Context) (*r.MembershipIndex, erro // the types of inputs to this handler matches the MemberRegistered event/proc defined in the MembershipContract interface type RegistrationEventHandler = func(pubkey r.IDCommitment, index r.MembershipIndex) error -func processLogs(evt *contracts.RLNMemberRegistered, handler RegistrationEventHandler) error { +func (rln *WakuRLNRelay) processLogs(evt *contracts.RLNMemberRegistered, handler RegistrationEventHandler) error { if evt == nil { return nil } @@ -113,7 +115,11 @@ func processLogs(evt *contracts.RLNMemberRegistered, handler RegistrationEventHa var pubkey r.IDCommitment = r.Bytes32(evt.Pubkey.Bytes()) index := r.MembershipIndex(uint(evt.Index.Int64())) + if index <= rln.lastIndexLoaded { + return nil + } + rln.lastIndexLoaded = index return handler(pubkey, index) } @@ -169,7 +175,7 @@ func (rln *WakuRLNRelay) loadOldEvents(rlnContract *contracts.RLN, handler Regis return logIterator.Error() } - err = processLogs(logIterator.Event, handler) + err = rln.processLogs(logIterator.Event, handler) if err != nil { return err } @@ -180,14 +186,21 @@ func (rln *WakuRLNRelay) loadOldEvents(rlnContract *contracts.RLN, handler Regis func (rln *WakuRLNRelay) watchNewEvents(rlnContract *contracts.RLN, handler RegistrationEventHandler, log *zap.Logger, doneCh chan struct{}, errCh chan error) { // Watch for new events logSink := make(chan *contracts.RLNMemberRegistered) - subs, err := rlnContract.WatchMemberRegistered(&bind.WatchOpts{Context: rln.ctx, Start: nil}, logSink) - if err != nil { - if err == rpc.ErrNotificationsUnsupported { - err = errors.New("notifications not supported. The node must support websockets") + + subs := event.Resubscribe(2*time.Second, func(ctx context.Context) (event.Subscription, error) { + subs, err := rlnContract.WatchMemberRegistered(&bind.WatchOpts{Context: rln.ctx, Start: nil}, logSink) + if err != nil { + if err == rpc.ErrNotificationsUnsupported { + err = errors.New("notifications not supported. The node must support websockets") + } + errCh <- err + subs.Unsubscribe() } - errCh <- err - return - } + + rln.log.Error("subscribing to rln events", zap.Error(err)) + + return subs, err + }) defer subs.Unsubscribe() close(doneCh) @@ -195,7 +208,7 @@ func (rln *WakuRLNRelay) watchNewEvents(rlnContract *contracts.RLN, handler Regi for { select { case evt := <-logSink: - err = processLogs(evt, handler) + err := rln.processLogs(evt, handler) if err != nil { rln.log.Error("processing rln log", zap.Error(err)) } diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/store/waku_store.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/store/waku_store.go index 2fc601d02..e29e0e3e6 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/store/waku_store.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/store/waku_store.go @@ -8,10 +8,10 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" - libp2pProtocol "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" + libp2pProtocol "github.com/libp2p/go-libp2p/core/protocol" "github.com/libp2p/go-msgio/protoio" "go.uber.org/zap" @@ -474,6 +474,13 @@ func (store *WakuStore) Query(ctx context.Context, query Query, opts ...HistoryR return nil, errors.New("invalid cursor") } + var messageIDs [][]byte + for _, m := range response.Messages { + messageID, _, _ := m.Hash() + messageIDs = append(messageIDs, messageID) + } + store.log.Info("retrieved", logging.HexArray("messageIDs", messageIDs...)) + result := &Result{ Messages: response.Messages, query: q, diff --git a/vendor/github.com/status-im/go-waku/waku/v2/protocol/swap/waku_swap.go b/vendor/github.com/status-im/go-waku/waku/v2/protocol/swap/waku_swap.go index be7ca5f56..b77f831e7 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/protocol/swap/waku_swap.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/protocol/swap/waku_swap.go @@ -3,7 +3,7 @@ package swap import ( "sync" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/protocol" "go.uber.org/zap" ) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/utils/crypto.go b/vendor/github.com/status-im/go-waku/waku/v2/utils/crypto.go index bcf3b6034..3b917eed5 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/utils/crypto.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/utils/crypto.go @@ -4,10 +4,10 @@ import ( "crypto/ecdsa" "github.com/btcsuite/btcd/btcec/v2" - "github.com/libp2p/go-libp2p-core/crypto" + "github.com/libp2p/go-libp2p/core/crypto" ) -// EcdsaPubKeyToSecp256k1PublicKey converts an `ecdsa.PublicKey` into a libp2p `crypto.Secp256k1PublicKey`` +// EcdsaPubKeyToSecp256k1PublicKey converts an `ecdsa.PublicKey` into a libp2p `crypto.Secp256k1PublicKey“ func EcdsaPubKeyToSecp256k1PublicKey(pubKey *ecdsa.PublicKey) *crypto.Secp256k1PublicKey { xFieldVal := &btcec.FieldVal{} yFieldVal := &btcec.FieldVal{} @@ -16,7 +16,7 @@ func EcdsaPubKeyToSecp256k1PublicKey(pubKey *ecdsa.PublicKey) *crypto.Secp256k1P return (*crypto.Secp256k1PublicKey)(btcec.NewPublicKey(xFieldVal, yFieldVal)) } -// EcdsaPubKeyToSecp256k1PublicKey converts an `ecdsa.PrivateKey` into a libp2p `crypto.Secp256k1PrivateKey`` +// EcdsaPubKeyToSecp256k1PublicKey converts an `ecdsa.PrivateKey` into a libp2p `crypto.Secp256k1PrivateKey“ func EcdsaPrivKeyToSecp256k1PrivKey(privKey *ecdsa.PrivateKey) *crypto.Secp256k1PrivateKey { privK, _ := btcec.PrivKeyFromBytes(privKey.D.Bytes()) return (*crypto.Secp256k1PrivateKey)(privK) diff --git a/vendor/github.com/status-im/go-waku/waku/v2/utils/enr.go b/vendor/github.com/status-im/go-waku/waku/v2/utils/enr.go index e30478933..6e8bb9a21 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/utils/enr.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/utils/enr.go @@ -11,8 +11,8 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" - "github.com/libp2p/go-libp2p-core/peer" - ma "github.com/multiformats/go-multiaddr" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/multiformats/go-multiaddr" "go.uber.org/zap" ) @@ -50,12 +50,12 @@ func NewWakuEnrBitfield(lightpush, filter, store, relay bool) WakuEnrBitfield { } // GetENRandIP returns a enr Node and TCP address obtained from a multiaddress. priv key and protocols supported -func GetENRandIP(addr ma.Multiaddr, wakuFlags WakuEnrBitfield, privK *ecdsa.PrivateKey) (*enode.Node, *net.TCPAddr, error) { +func GetENRandIP(addr multiaddr.Multiaddr, wakuFlags WakuEnrBitfield, privK *ecdsa.PrivateKey) (*enode.Node, *net.TCPAddr, error) { var ip string - dns4, err := addr.ValueForProtocol(ma.P_DNS4) + dns4, err := addr.ValueForProtocol(multiaddr.P_DNS4) if err != nil { - ip, err = addr.ValueForProtocol(ma.P_IP4) + ip, err = addr.ValueForProtocol(multiaddr.P_IP4) if err != nil { return nil, nil, err } @@ -67,7 +67,7 @@ func GetENRandIP(addr ma.Multiaddr, wakuFlags WakuEnrBitfield, privK *ecdsa.Priv ip = netIP.String() } - portStr, err := addr.ValueForProtocol(ma.P_TCP) + portStr, err := addr.ValueForProtocol(multiaddr.P_TCP) if err != nil { return nil, nil, err } @@ -90,26 +90,26 @@ func GetENRandIP(addr ma.Multiaddr, wakuFlags WakuEnrBitfield, privK *ecdsa.Priv return nil, nil, fmt.Errorf("could not set port %d", port) } - var multiaddrItems []ma.Multiaddr + var multiaddrItems []multiaddr.Multiaddr // 31/WAKU2-ENR - _, err = addr.ValueForProtocol(ma.P_WS) + _, err = addr.ValueForProtocol(multiaddr.P_WS) if err == nil { multiaddrItems = append(multiaddrItems, addr) } - _, err = addr.ValueForProtocol(ma.P_WSS) + _, err = addr.ValueForProtocol(multiaddr.P_WSS) if err == nil { multiaddrItems = append(multiaddrItems, addr) } - p2p, err := addr.ValueForProtocol(ma.P_P2P) + p2p, err := addr.ValueForProtocol(multiaddr.P_P2P) if err != nil { return nil, nil, err } - p2pAddr, err := ma.NewMultiaddr("/p2p/" + p2p) + p2pAddr, err := multiaddr.NewMultiaddr("/p2p/" + p2p) if err != nil { return nil, nil, fmt.Errorf("could not create p2p addr: %w", err) } @@ -142,18 +142,18 @@ func GetENRandIP(addr ma.Multiaddr, wakuFlags WakuEnrBitfield, privK *ecdsa.Priv } // EnodeToMultiaddress converts an enode into a multiaddress -func enodeToMultiAddr(node *enode.Node) (ma.Multiaddr, error) { +func enodeToMultiAddr(node *enode.Node) (multiaddr.Multiaddr, error) { pubKey := EcdsaPubKeyToSecp256k1PublicKey(node.Pubkey()) peerID, err := peer.IDFromPublicKey(pubKey) if err != nil { return nil, err } - return ma.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", node.IP(), node.TCP(), peerID)) + return multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d/p2p/%s", node.IP(), node.TCP(), peerID)) } // Multiaddress is used to extract all the multiaddresses that are part of a ENR record -func Multiaddress(node *enode.Node) ([]ma.Multiaddr, error) { +func Multiaddress(node *enode.Node) ([]multiaddr.Multiaddr, error) { pubKey := EcdsaPubKeyToSecp256k1PublicKey(node.Pubkey()) peerID, err := peer.IDFromPublicKey(pubKey) if err != nil { @@ -168,7 +168,7 @@ func Multiaddress(node *enode.Node) ([]ma.Multiaddr, error) { if err != nil { return nil, err } - return []ma.Multiaddr{addr}, nil + return []multiaddr.Multiaddr{addr}, nil } return nil, err } @@ -177,12 +177,12 @@ func Multiaddress(node *enode.Node) ([]ma.Multiaddr, error) { return nil, errors.New("invalid multiaddress field length") } - hostInfo, err := ma.NewMultiaddr(fmt.Sprintf("/p2p/%s", peerID.Pretty())) + hostInfo, err := multiaddr.NewMultiaddr(fmt.Sprintf("/p2p/%s", peerID.Pretty())) if err != nil { return nil, err } - var result []ma.Multiaddr + var result []multiaddr.Multiaddr offset := 0 for { maSize := binary.BigEndian.Uint16(multiaddrRaw[offset : offset+2]) @@ -190,7 +190,7 @@ func Multiaddress(node *enode.Node) ([]ma.Multiaddr, error) { return nil, errors.New("invalid multiaddress field length") } maRaw := multiaddrRaw[offset+2 : offset+2+int(maSize)] - addr, err := ma.NewMultiaddrBytes(maRaw) + addr, err := multiaddr.NewMultiaddrBytes(maRaw) if err != nil { return nil, fmt.Errorf("invalid multiaddress field length") } diff --git a/vendor/github.com/status-im/go-waku/waku/v2/utils/logger.go b/vendor/github.com/status-im/go-waku/waku/v2/utils/logger.go index a64721489..a38326d3c 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/utils/logger.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/utils/logger.go @@ -1,56 +1,54 @@ package utils import ( - "fmt" + "strings" + + logging "github.com/ipfs/go-log/v2" "go.uber.org/zap" - "go.uber.org/zap/zapcore" ) var log *zap.Logger = nil -var atom = zap.NewAtomicLevel() - -// SetLogLevel sets a custom log level -func SetLogLevel(level string) error { - lvl := zapcore.InfoLevel // zero value - err := lvl.Set(level) - if err != nil { - return err - } - atom.SetLevel(lvl) - return nil -} // Logger creates a zap.Logger with some reasonable defaults func Logger() *zap.Logger { if log == nil { - InitLogger("console") + InitLogger("console", "stdout") } return log } // InitLogger initializes a global logger using an specific encoding -func InitLogger(encoding string) { - cfg := zap.Config{ - Encoding: encoding, - Level: atom, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, - EncoderConfig: zapcore.EncoderConfig{ - MessageKey: "message", - LevelKey: "level", - EncodeLevel: zapcore.CapitalLevelEncoder, - TimeKey: "time", - EncodeTime: zapcore.ISO8601TimeEncoder, - NameKey: "caller", - EncodeCaller: zapcore.ShortCallerEncoder, - }, +func InitLogger(encoding string, output string) { + cfg := logging.GetConfig() + + if encoding == "json" { + cfg.Format = logging.JSONOutput + } else if encoding == "nocolor" { + cfg.Format = logging.PlaintextOutput + } else { + cfg.Format = logging.ColorizedOutput } - logger, err := cfg.Build() - if err != nil { - panic(fmt.Errorf("could not create logger: %s", err.Error())) + if output == "stdout" || output == "" { + cfg.Stdout = true + cfg.Stderr = false + } else { + if encoding == "console" { + cfg.Format = logging.PlaintextOutput + } + cfg.Stdout = false + cfg.Stderr = false + + outputParts := strings.Split(output, ":") + if len(outputParts) == 2 { + cfg.File = outputParts[1] + } else { + cfg.File = "./waku.log" + } } - log = logger.Named("gowaku") + logging.SetupLogging(cfg) + + log = logging.Logger("gowaku").Desugar() } diff --git a/vendor/github.com/status-im/go-waku/waku/v2/utils/peer.go b/vendor/github.com/status-im/go-waku/waku/v2/utils/peer.go index c58e47ae8..af94f1986 100644 --- a/vendor/github.com/status-im/go-waku/waku/v2/utils/peer.go +++ b/vendor/github.com/status-im/go-waku/waku/v2/utils/peer.go @@ -7,8 +7,8 @@ import ( "sync" "time" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/p2p/protocol/ping" "github.com/status-im/go-waku/logging" "go.uber.org/zap" diff --git a/vendor/github.com/status-im/rendezvous/client.go b/vendor/github.com/status-im/rendezvous/client.go index 35943ecb2..cf8328f12 100644 --- a/vendor/github.com/status-im/rendezvous/client.go +++ b/vendor/github.com/status-im/rendezvous/client.go @@ -10,10 +10,10 @@ import ( "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" libp2p "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/peer" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/peer" ma "github.com/multiformats/go-multiaddr" ethv4 "github.com/status-im/go-multiaddr-ethv4" "github.com/status-im/rendezvous/protocol" diff --git a/vendor/github.com/status-im/rendezvous/server/server.go b/vendor/github.com/status-im/rendezvous/server/server.go index e3f532a49..ef452e5f4 100644 --- a/vendor/github.com/status-im/rendezvous/server/server.go +++ b/vendor/github.com/status-im/rendezvous/server/server.go @@ -12,9 +12,9 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/rlp" "github.com/libp2p/go-libp2p" - "github.com/libp2p/go-libp2p-core/crypto" - "github.com/libp2p/go-libp2p-core/host" - "github.com/libp2p/go-libp2p-core/network" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/host" + "github.com/libp2p/go-libp2p/core/network" "github.com/multiformats/go-multiaddr" ma "github.com/multiformats/go-multiaddr" "github.com/status-im/rendezvous/protocol" diff --git a/vendor/github.com/status-im/rendezvous/stream.go b/vendor/github.com/status-im/rendezvous/stream.go index 0ed1063c5..e544e5a07 100644 --- a/vendor/github.com/status-im/rendezvous/stream.go +++ b/vendor/github.com/status-im/rendezvous/stream.go @@ -4,8 +4,8 @@ import ( "time" "github.com/ethereum/go-ethereum/metrics" - "github.com/libp2p/go-libp2p-core/network" - "github.com/libp2p/go-libp2p-core/protocol" + "github.com/libp2p/go-libp2p/core/network" + "github.com/libp2p/go-libp2p/core/protocol" ) var ( diff --git a/vendor/github.com/urfave/cli/v2/app.go b/vendor/github.com/urfave/cli/v2/app.go index 9f72f1b4f..24704e8f7 100644 --- a/vendor/github.com/urfave/cli/v2/app.go +++ b/vendor/github.com/urfave/cli/v2/app.go @@ -7,7 +7,6 @@ import ( "io" "os" "path/filepath" - "reflect" "sort" "time" ) @@ -112,6 +111,8 @@ type App struct { Suggest bool didSetup bool + + rootCommand *Command } type SuggestFlagFunc func(flags []Flag, provided string, hideHelp bool) string @@ -197,9 +198,11 @@ func (a *App) Setup() { var newCommands []*Command for _, c := range a.Commands { - if c.HelpName == "" { - c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) + cname := c.Name + if c.HelpName != "" { + cname = c.HelpName } + c.HelpName = fmt.Sprintf("%s %s", a.HelpName, cname) c.flagCategories = newFlagCategoriesFromFlags(c.Flags) newCommands = append(newCommands, c) @@ -229,7 +232,9 @@ func (a *App) Setup() { a.flagCategories = newFlagCategories() for _, fl := range a.Flags { if cf, ok := fl.(CategorizableFlag); ok { - a.flagCategories.AddFlag(cf.GetCategory(), cf) + if cf.GetCategory() != "" { + a.flagCategories.AddFlag(cf.GetCategory(), cf) + } } } @@ -238,6 +243,31 @@ func (a *App) Setup() { } } +func (a *App) newRootCommand() *Command { + return &Command{ + Name: a.Name, + Usage: a.Usage, + UsageText: a.UsageText, + Description: a.Description, + ArgsUsage: a.ArgsUsage, + BashComplete: a.BashComplete, + Before: a.Before, + After: a.After, + Action: a.Action, + OnUsageError: a.OnUsageError, + Subcommands: a.Commands, + Flags: a.Flags, + flagCategories: a.flagCategories, + HideHelp: a.HideHelp, + HideHelpCommand: a.HideHelpCommand, + UseShortOptionHandling: a.UseShortOptionHandling, + HelpName: a.HelpName, + CustomHelpTemplate: a.CustomAppHelpTemplate, + categories: a.categories, + isRoot: true, + } +} + func (a *App) newFlagSet() (*flag.FlagSet, error) { return flagSet(a.Name, a.Flags) } @@ -266,136 +296,20 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) { // always appends the completion flag at the end of the command shellComplete, arguments := checkShellCompleteFlag(a, arguments) - set, err := a.newFlagSet() - if err != nil { - return err - } - - err = parseIter(set, a, arguments[1:], shellComplete) - nerr := normalizeFlags(a.Flags, set) - cCtx := NewContext(a, set, &Context{Context: ctx}) - if nerr != nil { - _, _ = fmt.Fprintln(a.Writer, nerr) - if !a.HideHelp { - _ = ShowAppHelp(cCtx) - } - return nerr - } + cCtx := NewContext(a, nil, &Context{Context: ctx}) cCtx.shellComplete = shellComplete - if checkCompletions(cCtx) { - return nil - } + a.rootCommand = a.newRootCommand() + cCtx.Command = a.rootCommand - if err != nil { - if a.OnUsageError != nil { - err := a.OnUsageError(cCtx, err, false) - a.handleExitCoder(cCtx, err) - return err - } - _, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) - if a.Suggest { - if suggestion, err := a.suggestFlagFromError(err, ""); err == nil { - fmt.Fprintf(a.Writer, suggestion) - } - } - if !a.HideHelp { - _ = ShowAppHelp(cCtx) - } - return err - } + return a.rootCommand.Run(cCtx, arguments...) +} - if a.After != nil && !cCtx.shellComplete { - defer func() { - if afterErr := a.After(cCtx); afterErr != nil { - if err != nil { - err = newMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if !a.HideHelp && checkHelp(cCtx) { - _ = ShowAppHelp(cCtx) - return nil - } - - if !a.HideVersion && checkVersion(cCtx) { - ShowVersion(cCtx) - return nil - } - - cerr := cCtx.checkRequiredFlags(a.Flags) - if cerr != nil { - _ = ShowAppHelp(cCtx) - return cerr - } - - if a.Before != nil && !cCtx.shellComplete { - beforeErr := a.Before(cCtx) - if beforeErr != nil { - a.handleExitCoder(cCtx, beforeErr) - err = beforeErr - return err - } - } - - if err = runFlagActions(cCtx, a.Flags); err != nil { - return err - } - - var c *Command - args := cCtx.Args() - if args.Present() { - name := args.First() - if a.validCommandName(name) { - c = a.Command(name) - } else { - hasDefault := a.DefaultCommand != "" - isFlagName := checkStringSliceIncludes(name, cCtx.FlagNames()) - - var ( - isDefaultSubcommand = false - defaultHasSubcommands = false - ) - - if hasDefault { - dc := a.Command(a.DefaultCommand) - defaultHasSubcommands = len(dc.Subcommands) > 0 - for _, dcSub := range dc.Subcommands { - if checkStringSliceIncludes(name, dcSub.Names()) { - isDefaultSubcommand = true - break - } - } - } - - if isFlagName || (hasDefault && (defaultHasSubcommands && isDefaultSubcommand)) { - argsWithDefault := a.argsWithDefaultCommand(args) - if !reflect.DeepEqual(args, argsWithDefault) { - c = a.Command(argsWithDefault.First()) - } - } - } - } else if a.DefaultCommand != "" { - c = a.Command(a.DefaultCommand) - } - - if c != nil { - return c.Run(cCtx) - } - - if a.Action == nil { - a.Action = helpCommand.Action - } - - // Run default Action - err = a.Action(cCtx) - - a.handleExitCoder(cCtx, err) - return err +// This is a stub function to keep public API unchanged from old code +// +// Deprecated: use App.Run or App.RunContext +func (a *App) RunAsSubcommand(ctx *Context) (err error) { + return a.RunContext(ctx.Context, ctx.Args().Slice()) } func (a *App) suggestFlagFromError(err error, command string) (string, error) { @@ -405,15 +319,17 @@ func (a *App) suggestFlagFromError(err error, command string) (string, error) { } flags := a.Flags + hideHelp := a.HideHelp if command != "" { cmd := a.Command(command) if cmd == nil { return "", err } flags = cmd.Flags + hideHelp = hideHelp || cmd.HideHelp } - suggestion := SuggestFlag(flags, flag, a.HideHelp) + suggestion := SuggestFlag(flags, flag, hideHelp) if len(suggestion) == 0 { return "", err } @@ -433,120 +349,6 @@ func (a *App) RunAndExitOnError() { } } -// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to -// generate command-specific flags -func (a *App) RunAsSubcommand(ctx *Context) (err error) { - // Setup also handles HideHelp and HideHelpCommand - a.Setup() - - var newCmds []*Command - for _, c := range a.Commands { - if c.HelpName == "" { - c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) - } - newCmds = append(newCmds, c) - } - a.Commands = newCmds - - set, err := a.newFlagSet() - if err != nil { - return err - } - - err = parseIter(set, a, ctx.Args().Tail(), ctx.shellComplete) - nerr := normalizeFlags(a.Flags, set) - cCtx := NewContext(a, set, ctx) - - if nerr != nil { - _, _ = fmt.Fprintln(a.Writer, nerr) - _, _ = fmt.Fprintln(a.Writer) - if len(a.Commands) > 0 { - _ = ShowSubcommandHelp(cCtx) - } else { - _ = ShowCommandHelp(ctx, cCtx.Args().First()) - } - return nerr - } - - if checkCompletions(cCtx) { - return nil - } - - if err != nil { - if a.OnUsageError != nil { - err = a.OnUsageError(cCtx, err, true) - a.handleExitCoder(cCtx, err) - return err - } - _, _ = fmt.Fprintf(a.Writer, "%s %s\n\n", "Incorrect Usage.", err.Error()) - if a.Suggest { - if suggestion, err := a.suggestFlagFromError(err, cCtx.Command.Name); err == nil { - fmt.Fprintf(a.Writer, suggestion) - } - } - _ = ShowSubcommandHelp(cCtx) - return err - } - - if len(a.Commands) > 0 { - if checkSubcommandHelp(cCtx) { - return nil - } - } else { - if checkCommandHelp(ctx, cCtx.Args().First()) { - return nil - } - } - - cerr := cCtx.checkRequiredFlags(a.Flags) - if cerr != nil { - _ = ShowSubcommandHelp(cCtx) - return cerr - } - - if a.After != nil && !cCtx.shellComplete { - defer func() { - afterErr := a.After(cCtx) - if afterErr != nil { - a.handleExitCoder(cCtx, err) - if err != nil { - err = newMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if a.Before != nil && !cCtx.shellComplete { - beforeErr := a.Before(cCtx) - if beforeErr != nil { - a.handleExitCoder(cCtx, beforeErr) - err = beforeErr - return err - } - } - - if err = runFlagActions(cCtx, a.Flags); err != nil { - return err - } - - args := cCtx.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(cCtx) - } - } - - // Run default Action - err = a.Action(cCtx) - - a.handleExitCoder(cCtx, err) - return err -} - // Command returns the named command on App. Returns nil if the command does not exist func (a *App) Command(name string) *Command { for _, c := range a.Commands { diff --git a/vendor/github.com/urfave/cli/v2/category.go b/vendor/github.com/urfave/cli/v2/category.go index 8bf325e20..7aca0c768 100644 --- a/vendor/github.com/urfave/cli/v2/category.go +++ b/vendor/github.com/urfave/cli/v2/category.go @@ -102,7 +102,9 @@ func newFlagCategoriesFromFlags(fs []Flag) FlagCategories { fc := newFlagCategories() for _, fl := range fs { if cf, ok := fl.(CategorizableFlag); ok { - fc.AddFlag(cf.GetCategory(), cf) + if cf.GetCategory() != "" { + fc.AddFlag(cf.GetCategory(), cf) + } } } diff --git a/vendor/github.com/urfave/cli/v2/cli.go b/vendor/github.com/urfave/cli/v2/cli.go index b3b864cf5..28ad0582b 100644 --- a/vendor/github.com/urfave/cli/v2/cli.go +++ b/vendor/github.com/urfave/cli/v2/cli.go @@ -22,4 +22,4 @@ // } package cli -//go:generate go run cmd/urfave-cli-genflags/main.go +//go:generate make -C cmd/urfave-cli-genflags run diff --git a/vendor/github.com/urfave/cli/v2/command.go b/vendor/github.com/urfave/cli/v2/command.go index d24b61e23..a63048dbd 100644 --- a/vendor/github.com/urfave/cli/v2/command.go +++ b/vendor/github.com/urfave/cli/v2/command.go @@ -3,6 +3,7 @@ package cli import ( "flag" "fmt" + "reflect" "sort" "strings" ) @@ -62,6 +63,12 @@ type Command struct { // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. CustomHelpTemplate string + + // categories contains the categorized commands and is populated on app startup + categories CommandCategories + + // if this is a root "special" command + isRoot bool } type Commands []*Command @@ -89,10 +96,21 @@ func (c *Command) FullName() string { return strings.Join(c.commandNamePath, " ") } -// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags -func (c *Command) Run(ctx *Context) (err error) { - if len(c.Subcommands) > 0 { - return c.startApp(ctx) +func (cmd *Command) Command(name string) *Command { + for _, c := range cmd.Subcommands { + if c.HasName(name) { + return c + } + } + + return nil +} + +func (c *Command) setup(ctx *Context) { + if c.Command(helpCommand.Name) == nil && !c.HideHelp { + if !c.HideHelpCommand { + c.Subcommands = append(c.Subcommands, helpCommand) + } } if !c.HideHelp && HelpFlag != nil { @@ -104,46 +122,72 @@ func (c *Command) Run(ctx *Context) (err error) { c.UseShortOptionHandling = true } - set, err := c.parseFlags(ctx.Args(), ctx.shellComplete) + c.categories = newCommandCategories() + for _, command := range c.Subcommands { + c.categories.AddCommand(command.Category, command) + } + sort.Sort(c.categories.(*commandCategories)) - cCtx := NewContext(ctx.App, set, ctx) - cCtx.Command = c - if checkCommandCompletions(cCtx, c.Name) { + var newCmds []*Command + for _, scmd := range c.Subcommands { + if scmd.HelpName == "" { + scmd.HelpName = fmt.Sprintf("%s %s", c.HelpName, scmd.Name) + } + newCmds = append(newCmds, scmd) + } + c.Subcommands = newCmds +} + +func (c *Command) Run(cCtx *Context, arguments ...string) (err error) { + + if !c.isRoot { + c.setup(cCtx) + } + + a := args(arguments) + set, err := c.parseFlags(&a, cCtx.shellComplete) + cCtx.flagSet = set + + if c.isRoot { + if checkCompletions(cCtx) { + return nil + } + } else if checkCommandCompletions(cCtx, c.Name) { return nil } if err != nil { if c.OnUsageError != nil { - err = c.OnUsageError(cCtx, err, false) + err = c.OnUsageError(cCtx, err, !c.isRoot) cCtx.App.handleExitCoder(cCtx, err) return err } - _, _ = fmt.Fprintln(cCtx.App.Writer, "Incorrect Usage:", err.Error()) - _, _ = fmt.Fprintln(cCtx.App.Writer) - if ctx.App.Suggest { - if suggestion, err := ctx.App.suggestFlagFromError(err, c.Name); err == nil { - fmt.Fprintf(cCtx.App.Writer, suggestion) + _, _ = fmt.Fprintf(cCtx.App.Writer, "%s %s\n\n", "Incorrect Usage:", err.Error()) + if cCtx.App.Suggest { + if suggestion, err := c.suggestFlagFromError(err, ""); err == nil { + fmt.Fprintf(cCtx.App.Writer, "%s", suggestion) } } if !c.HideHelp { - _ = ShowCommandHelp(cCtx, c.Name) + if c.isRoot { + _ = ShowAppHelp(cCtx) + } else { + _ = ShowCommandHelp(cCtx.parentContext, c.Name) + } } return err } - if checkCommandHelp(cCtx, c.Name) { + if checkHelp(cCtx) { + return helpCommand.Action(cCtx) + } + + if c.isRoot && !cCtx.App.HideVersion && checkVersion(cCtx) { + ShowVersion(cCtx) return nil } - cerr := cCtx.checkRequiredFlags(c.Flags) - if cerr != nil { - if !c.HideHelp { - _ = ShowCommandHelp(cCtx, c.Name) - } - return cerr - } - - if c.After != nil { + if c.After != nil && !cCtx.shellComplete { defer func() { afterErr := c.After(cCtx) if afterErr != nil { @@ -157,10 +201,17 @@ func (c *Command) Run(ctx *Context) (err error) { }() } - if c.Before != nil { - err = c.Before(cCtx) - if err != nil { - cCtx.App.handleExitCoder(cCtx, err) + cerr := cCtx.checkRequiredFlags(c.Flags) + if cerr != nil { + _ = ShowSubcommandHelp(cCtx) + return cerr + } + + if c.Before != nil && !cCtx.shellComplete { + beforeErr := c.Before(cCtx) + if beforeErr != nil { + cCtx.App.handleExitCoder(cCtx, beforeErr) + err = beforeErr return err } } @@ -169,16 +220,57 @@ func (c *Command) Run(ctx *Context) (err error) { return err } + var cmd *Command + args := cCtx.Args() + if args.Present() { + name := args.First() + cmd = c.Command(name) + if cmd == nil { + hasDefault := cCtx.App.DefaultCommand != "" + isFlagName := checkStringSliceIncludes(name, cCtx.FlagNames()) + + var ( + isDefaultSubcommand = false + defaultHasSubcommands = false + ) + + if hasDefault { + dc := cCtx.App.Command(cCtx.App.DefaultCommand) + defaultHasSubcommands = len(dc.Subcommands) > 0 + for _, dcSub := range dc.Subcommands { + if checkStringSliceIncludes(name, dcSub.Names()) { + isDefaultSubcommand = true + break + } + } + } + + if isFlagName || (hasDefault && (defaultHasSubcommands && isDefaultSubcommand)) { + argsWithDefault := cCtx.App.argsWithDefaultCommand(args) + if !reflect.DeepEqual(args, argsWithDefault) { + cmd = cCtx.App.rootCommand.Command(argsWithDefault.First()) + } + } + } + } else if cCtx.App.DefaultCommand != "" { + if dc := cCtx.App.Command(cCtx.App.DefaultCommand); dc != c { + cmd = dc + } + } + + if cmd != nil { + newcCtx := NewContext(cCtx.App, nil, cCtx) + newcCtx.Command = cmd + return cmd.Run(newcCtx, cCtx.Args().Slice()...) + } + if c.Action == nil { c.Action = helpCommand.Action } - cCtx.Command = c err = c.Action(cCtx) - if err != nil { - cCtx.App.handleExitCoder(cCtx, err) - } + cCtx.App.handleExitCoder(cCtx, err) return err } @@ -190,6 +282,31 @@ func (c *Command) useShortOptionHandling() bool { return c.UseShortOptionHandling } +func (c *Command) suggestFlagFromError(err error, command string) (string, error) { + flag, parseErr := flagFromError(err) + if parseErr != nil { + return "", err + } + + flags := c.Flags + hideHelp := c.HideHelp + if command != "" { + cmd := c.Command(command) + if cmd == nil { + return "", err + } + flags = cmd.Flags + hideHelp = hideHelp || cmd.HideHelp + } + + suggestion := SuggestFlag(flags, flag, hideHelp) + if len(suggestion) == 0 { + return "", err + } + + return fmt.Sprintf(SuggestDidYouMeanTemplate, suggestion) + "\n\n", nil +} + func (c *Command) parseFlags(args Args, shellComplete bool) (*flag.FlagSet, error) { set, err := c.newFlagSet() if err != nil { @@ -228,82 +345,38 @@ func (c *Command) HasName(name string) bool { return false } -func (c *Command) startApp(ctx *Context) error { - app := &App{ - Metadata: ctx.App.Metadata, - Name: fmt.Sprintf("%s %s", ctx.App.Name, c.Name), +// VisibleCategories returns a slice of categories and commands that are +// Hidden=false +func (c *Command) VisibleCategories() []CommandCategory { + ret := []CommandCategory{} + for _, category := range c.categories.Categories() { + if visible := func() CommandCategory { + if len(category.VisibleCommands()) > 0 { + return category + } + return nil + }(); visible != nil { + ret = append(ret, visible) + } } + return ret +} - if c.HelpName == "" { - app.HelpName = c.HelpName - } else { - app.HelpName = app.Name - } - - app.Usage = c.Usage - app.UsageText = c.UsageText - app.Description = c.Description - app.ArgsUsage = c.ArgsUsage - - // set CommandNotFound - app.CommandNotFound = ctx.App.CommandNotFound - app.CustomAppHelpTemplate = c.CustomHelpTemplate - - // set the flags and commands - app.Commands = c.Subcommands - app.Flags = c.Flags - app.HideHelp = c.HideHelp - app.HideHelpCommand = c.HideHelpCommand - - app.Version = ctx.App.Version - app.HideVersion = true - app.Compiled = ctx.App.Compiled - app.Reader = ctx.App.Reader - app.Writer = ctx.App.Writer - app.ErrWriter = ctx.App.ErrWriter - app.ExitErrHandler = ctx.App.ExitErrHandler - app.UseShortOptionHandling = ctx.App.UseShortOptionHandling - app.Suggest = ctx.App.Suggest - - app.categories = newCommandCategories() +// VisibleCommands returns a slice of the Commands with Hidden=false +func (c *Command) VisibleCommands() []*Command { + var ret []*Command for _, command := range c.Subcommands { - app.categories.AddCommand(command.Category, command) + if !command.Hidden { + ret = append(ret, command) + } } - - sort.Sort(app.categories.(*commandCategories)) - - // bash completion - app.EnableBashCompletion = ctx.App.EnableBashCompletion - if c.BashComplete != nil { - app.BashComplete = c.BashComplete - } - - // set the actions - app.Before = c.Before - app.After = c.After - if c.Action != nil { - app.Action = c.Action - } else { - app.Action = helpCommand.Action - } - app.OnUsageError = c.OnUsageError - - for index, cc := range app.Commands { - app.Commands[index].commandNamePath = []string{c.Name, cc.Name} - } - - return app.RunAsSubcommand(ctx) + return ret } // VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain func (c *Command) VisibleFlagCategories() []VisibleFlagCategory { if c.flagCategories == nil { - c.flagCategories = newFlagCategories() - for _, fl := range c.Flags { - if cf, ok := fl.(CategorizableFlag); ok { - c.flagCategories.AddFlag(cf.GetCategory(), cf) - } - } + c.flagCategories = newFlagCategoriesFromFlags(c.Flags) } return c.flagCategories.VisibleCategories() } diff --git a/vendor/github.com/urfave/cli/v2/flag_bool.go b/vendor/github.com/urfave/cli/v2/flag_bool.go index 0be27e3aa..f64d1cd92 100644 --- a/vendor/github.com/urfave/cli/v2/flag_bool.go +++ b/vendor/github.com/urfave/cli/v2/flag_bool.go @@ -84,7 +84,7 @@ func (f *BoolFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return fmt.Sprintf("%v", f.Value) + return fmt.Sprintf("%v", f.defaultValue) } // GetEnvVars returns the env vars for this flag @@ -103,6 +103,9 @@ func (f *BoolFlag) RunAction(c *Context) error { // Apply populates the flag given the flag set and environment func (f *BoolFlag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { valBool, err := strconv.ParseBool(val) diff --git a/vendor/github.com/urfave/cli/v2/flag_duration.go b/vendor/github.com/urfave/cli/v2/flag_duration.go index 31db4102e..eac4cb833 100644 --- a/vendor/github.com/urfave/cli/v2/flag_duration.go +++ b/vendor/github.com/urfave/cli/v2/flag_duration.go @@ -32,7 +32,7 @@ func (f *DurationFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return f.GetValue() + return f.defaultValue.String() } // GetEnvVars returns the env vars for this flag @@ -42,6 +42,9 @@ func (f *DurationFlag) GetEnvVars() []string { // Apply populates the flag given the flag set and environment func (f *DurationFlag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { valDuration, err := time.ParseDuration(val) diff --git a/vendor/github.com/urfave/cli/v2/flag_generic.go b/vendor/github.com/urfave/cli/v2/flag_generic.go index 358bd966e..4f9ac0a7f 100644 --- a/vendor/github.com/urfave/cli/v2/flag_generic.go +++ b/vendor/github.com/urfave/cli/v2/flag_generic.go @@ -11,6 +11,19 @@ type Generic interface { String() string } +type stringGeneric struct { + value string +} + +func (s *stringGeneric) Set(value string) error { + s.value = value + return nil +} + +func (s *stringGeneric) String() string { + return s.value +} + // TakesValue returns true of the flag takes a value, otherwise false func (f *GenericFlag) TakesValue() bool { return true @@ -40,7 +53,10 @@ func (f *GenericFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return f.GetValue() + if f.defaultValue != nil { + return f.defaultValue.String() + } + return "" } // GetEnvVars returns the env vars for this flag @@ -51,6 +67,11 @@ func (f *GenericFlag) GetEnvVars() []string { // Apply takes the flagset and calls Set on the generic flag with the value // provided by the user for parsing by the flag func (f *GenericFlag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + if f.Value != nil { + f.defaultValue = &stringGeneric{value: f.Value.String()} + } + if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { if err := f.Value.Set(val); err != nil { diff --git a/vendor/github.com/urfave/cli/v2/flag_int.go b/vendor/github.com/urfave/cli/v2/flag_int.go index af98e936f..d681270a2 100644 --- a/vendor/github.com/urfave/cli/v2/flag_int.go +++ b/vendor/github.com/urfave/cli/v2/flag_int.go @@ -32,7 +32,7 @@ func (f *IntFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return f.GetValue() + return fmt.Sprintf("%d", f.defaultValue) } // GetEnvVars returns the env vars for this flag @@ -42,6 +42,9 @@ func (f *IntFlag) GetEnvVars() []string { // Apply populates the flag given the flag set and environment func (f *IntFlag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { valInt, err := strconv.ParseInt(val, f.Base, 64) diff --git a/vendor/github.com/urfave/cli/v2/flag_int64.go b/vendor/github.com/urfave/cli/v2/flag_int64.go index ebe46d21f..6f8c8d27d 100644 --- a/vendor/github.com/urfave/cli/v2/flag_int64.go +++ b/vendor/github.com/urfave/cli/v2/flag_int64.go @@ -32,7 +32,7 @@ func (f *Int64Flag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return f.GetValue() + return fmt.Sprintf("%d", f.defaultValue) } // GetEnvVars returns the env vars for this flag @@ -42,6 +42,9 @@ func (f *Int64Flag) GetEnvVars() []string { // Apply populates the flag given the flag set and environment func (f *Int64Flag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { valInt, err := strconv.ParseInt(val, f.Base, 64) diff --git a/vendor/github.com/urfave/cli/v2/flag_path.go b/vendor/github.com/urfave/cli/v2/flag_path.go index 911819db9..6434d3224 100644 --- a/vendor/github.com/urfave/cli/v2/flag_path.go +++ b/vendor/github.com/urfave/cli/v2/flag_path.go @@ -33,10 +33,10 @@ func (f *PathFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - if f.Value == "" { - return f.Value + if f.defaultValue == "" { + return f.defaultValue } - return fmt.Sprintf("%q", f.Value) + return fmt.Sprintf("%q", f.defaultValue) } // GetEnvVars returns the env vars for this flag @@ -46,6 +46,9 @@ func (f *PathFlag) GetEnvVars() []string { // Apply populates the flag given the flag set and environment func (f *PathFlag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { f.Value = val f.HasBeenSet = true diff --git a/vendor/github.com/urfave/cli/v2/flag_string.go b/vendor/github.com/urfave/cli/v2/flag_string.go index b7163ba6f..3050086e8 100644 --- a/vendor/github.com/urfave/cli/v2/flag_string.go +++ b/vendor/github.com/urfave/cli/v2/flag_string.go @@ -31,10 +31,10 @@ func (f *StringFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - if f.Value == "" { - return f.Value + if f.defaultValue == "" { + return f.defaultValue } - return fmt.Sprintf("%q", f.Value) + return fmt.Sprintf("%q", f.defaultValue) } // GetEnvVars returns the env vars for this flag @@ -44,6 +44,9 @@ func (f *StringFlag) GetEnvVars() []string { // Apply populates the flag given the flag set and environment func (f *StringFlag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { f.Value = val f.HasBeenSet = true diff --git a/vendor/github.com/urfave/cli/v2/flag_timestamp.go b/vendor/github.com/urfave/cli/v2/flag_timestamp.go index 17bc8d757..fa0671fe4 100644 --- a/vendor/github.com/urfave/cli/v2/flag_timestamp.go +++ b/vendor/github.com/urfave/cli/v2/flag_timestamp.go @@ -72,6 +72,25 @@ func (t *Timestamp) Get() interface{} { return *t } +// clone timestamp +func (t *Timestamp) clone() *Timestamp { + tc := &Timestamp{ + timestamp: nil, + hasBeenSet: t.hasBeenSet, + layout: t.layout, + location: nil, + } + if t.timestamp != nil { + tts := *t.timestamp + tc.timestamp = &tts + } + if t.location != nil { + loc := *t.location + tc.location = &loc + } + return tc +} + // TakesValue returns true of the flag takes a value, otherwise false func (f *TimestampFlag) TakesValue() bool { return true @@ -101,7 +120,11 @@ func (f *TimestampFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return f.GetValue() + if f.defaultValue != nil && f.defaultValue.timestamp != nil { + return f.defaultValue.timestamp.String() + } + + return "" } // GetEnvVars returns the env vars for this flag @@ -120,6 +143,8 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error { f.Value.SetLayout(f.Layout) f.Value.SetLocation(f.Timezone) + f.defaultValue = f.Value.clone() + if f.Destination != nil { f.Destination.SetLayout(f.Layout) f.Destination.SetLocation(f.Timezone) diff --git a/vendor/github.com/urfave/cli/v2/flag_uint.go b/vendor/github.com/urfave/cli/v2/flag_uint.go index f9acb6d06..d11aa0a89 100644 --- a/vendor/github.com/urfave/cli/v2/flag_uint.go +++ b/vendor/github.com/urfave/cli/v2/flag_uint.go @@ -23,6 +23,9 @@ func (f *UintFlag) GetCategory() string { // Apply populates the flag given the flag set and environment func (f *UintFlag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { valInt, err := strconv.ParseUint(val, f.Base, 64) @@ -66,7 +69,7 @@ func (f *UintFlag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return f.GetValue() + return fmt.Sprintf("%d", f.defaultValue) } // GetEnvVars returns the env vars for this flag diff --git a/vendor/github.com/urfave/cli/v2/flag_uint64.go b/vendor/github.com/urfave/cli/v2/flag_uint64.go index 09590d735..ea73100a9 100644 --- a/vendor/github.com/urfave/cli/v2/flag_uint64.go +++ b/vendor/github.com/urfave/cli/v2/flag_uint64.go @@ -23,6 +23,9 @@ func (f *Uint64Flag) GetCategory() string { // Apply populates the flag given the flag set and environment func (f *Uint64Flag) Apply(set *flag.FlagSet) error { + // set default value so that environment wont be able to overwrite it + f.defaultValue = f.Value + if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val != "" { valInt, err := strconv.ParseUint(val, f.Base, 64) @@ -66,7 +69,7 @@ func (f *Uint64Flag) GetDefaultText() string { if f.DefaultText != "" { return f.DefaultText } - return f.GetValue() + return fmt.Sprintf("%d", f.defaultValue) } // GetEnvVars returns the env vars for this flag diff --git a/vendor/github.com/urfave/cli/v2/godoc-current.txt b/vendor/github.com/urfave/cli/v2/godoc-current.txt index 6b3c73974..80344eced 100644 --- a/vendor/github.com/urfave/cli/v2/godoc-current.txt +++ b/vendor/github.com/urfave/cli/v2/godoc-current.txt @@ -32,7 +32,7 @@ var ( SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate ) var AppHelpTemplate = `NAME: - {{$v := offset .Name 6}}{{wrap .Name 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}} + {{template "helpNameTemplate" .}} USAGE: {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} @@ -41,51 +41,39 @@ VERSION: {{.Version}}{{end}}{{end}}{{if .Description}} DESCRIPTION: - {{wrap .Description 3}}{{end}}{{if len .Authors}} + {{template "descriptionTemplate" .}}{{end}} +{{- if len .Authors}} -AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: - {{range $index, $author := .Authors}}{{if $index}} - {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}} +AUTHOR{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}} -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}} - {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}} +COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}} -GLOBAL OPTIONS:{{range .VisibleFlagCategories}} - {{if .Name}}{{.Name}} - {{end}}{{range .Flags}}{{.}} - {{end}}{{end}}{{else}}{{if .VisibleFlags}} +GLOBAL OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} -GLOBAL OPTIONS: - {{range $index, $option := .VisibleFlags}}{{if $index}} - {{end}}{{wrap $option.String 6}}{{end}}{{end}}{{end}}{{if .Copyright}} +GLOBAL OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}} COPYRIGHT: - {{wrap .Copyright 3}}{{end}} + {{template "copyrightTemplate" .}}{{end}} ` AppHelpTemplate is the text template for the Default help topic. cli.go uses text/template to render templates. You can render custom help text by setting this variable. var CommandHelpTemplate = `NAME: - {{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}} + {{template "helpNameTemplate" .}} USAGE: - {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}} + {{template "usageTemplate" .}}{{if .Category}} CATEGORY: {{.Category}}{{end}}{{if .Description}} DESCRIPTION: - {{wrap .Description 3}}{{end}}{{if .VisibleFlagCategories}} + {{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}} -OPTIONS:{{range .VisibleFlagCategories}} - {{if .Name}}{{.Name}} - {{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}} +OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} -OPTIONS: - {{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}} +OPTIONS:{{template "visibleFlagTemplate" .}}{{end}} ` CommandHelpTemplate is the text template for the command help topic. cli.go uses text/template to render templates. You can render custom help text by @@ -145,21 +133,19 @@ var OsExiter = os.Exit os.Exit. var SubcommandHelpTemplate = `NAME: - {{.HelpName}} - {{.Usage}} + {{template "helpNameTemplate" .}} USAGE: - {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} + {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} DESCRIPTION: - {{wrap .Description 3}}{{end}} + {{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}} -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}} - {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} +COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}} -OPTIONS: - {{range .VisibleFlags}}{{.}}{{end}}{{end}} +OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} + +OPTIONS:{{template "visibleFlagTemplate" .}}{{end}} ` SubcommandHelpTemplate is the text template for the subcommand help topic. cli.go uses text/template to render templates. You can render custom help @@ -362,8 +348,9 @@ func (a *App) RunAndExitOnError() code in the cli.ExitCoder func (a *App) RunAsSubcommand(ctx *Context) (err error) - RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() - to generate command-specific flags + This is a stub function to keep public API unchanged from old code + + Deprecated: use App.Run or App.RunContext func (a *App) RunContext(ctx context.Context, arguments []string) (err error) RunContext is like Run except it takes a Context that will be passed to @@ -460,6 +447,7 @@ type BoolFlag struct { Count *int Action func(*Context, bool) error + // Has unexported fields. } BoolFlag is a flag with type bool @@ -567,10 +555,13 @@ type Command struct { // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. CustomHelpTemplate string + // Has unexported fields. } Command is a subcommand for a cli.App. +func (cmd *Command) Command(name string) *Command + func (c *Command) FullName() string FullName returns the full name of the command. For subcommands this ensures that parent commands are part of the command path @@ -581,9 +572,14 @@ func (c *Command) HasName(name string) bool func (c *Command) Names() []string Names returns the names including short names and aliases. -func (c *Command) Run(ctx *Context) (err error) - Run invokes the command given the context, parses ctx.Args() to generate - command-specific flags +func (c *Command) Run(cCtx *Context, arguments ...string) (err error) + +func (c *Command) VisibleCategories() []CommandCategory + VisibleCategories returns a slice of categories and commands that are + Hidden=false + +func (c *Command) VisibleCommands() []*Command + VisibleCommands returns a slice of the Commands with Hidden=false func (c *Command) VisibleFlagCategories() []VisibleFlagCategory VisibleFlagCategories returns a slice containing all the visible flag @@ -780,6 +776,7 @@ type DurationFlag struct { EnvVars []string Action func(*Context, time.Duration) error + // Has unexported fields. } DurationFlag is a flag with type time.Duration @@ -958,6 +955,7 @@ type Float64Flag struct { EnvVars []string Action func(*Context, float64) error + // Has unexported fields. } Float64Flag is a flag with type float64 @@ -1046,6 +1044,7 @@ type Float64SliceFlag struct { EnvVars []string Action func(*Context, []float64) error + // Has unexported fields. } Float64SliceFlag is a flag with type *Float64Slice @@ -1128,6 +1127,7 @@ type GenericFlag struct { TakesFile bool Action func(*Context, interface{}) error + // Has unexported fields. } GenericFlag is a flag with type Generic @@ -1196,6 +1196,7 @@ type Int64Flag struct { Base int Action func(*Context, int64) error + // Has unexported fields. } Int64Flag is a flag with type int64 @@ -1284,6 +1285,7 @@ type Int64SliceFlag struct { EnvVars []string Action func(*Context, []int64) error + // Has unexported fields. } Int64SliceFlag is a flag with type *Int64Slice @@ -1360,6 +1362,7 @@ type IntFlag struct { Base int Action func(*Context, int) error + // Has unexported fields. } IntFlag is a flag with type int @@ -1452,6 +1455,7 @@ type IntSliceFlag struct { EnvVars []string Action func(*Context, []int) error + // Has unexported fields. } IntSliceFlag is a flag with type *IntSlice @@ -1562,6 +1566,7 @@ type PathFlag struct { TakesFile bool Action func(*Context, Path) error + // Has unexported fields. } PathFlag is a flag with type Path @@ -1704,6 +1709,7 @@ type StringFlag struct { TakesFile bool Action func(*Context, string) error + // Has unexported fields. } StringFlag is a flag with type string @@ -1794,6 +1800,7 @@ type StringSliceFlag struct { TakesFile bool Action func(*Context, []string) error + // Has unexported fields. } StringSliceFlag is a flag with type *StringSlice @@ -1905,6 +1912,7 @@ type TimestampFlag struct { Timezone *time.Location Action func(*Context, *time.Time) error + // Has unexported fields. } TimestampFlag is a flag with type *Timestamp @@ -1972,6 +1980,7 @@ type Uint64Flag struct { Base int Action func(*Context, uint64) error + // Has unexported fields. } Uint64Flag is a flag with type uint64 @@ -2060,6 +2069,7 @@ type Uint64SliceFlag struct { EnvVars []string Action func(*Context, []uint64) error + // Has unexported fields. } Uint64SliceFlag is a flag with type *Uint64Slice @@ -2127,6 +2137,7 @@ type UintFlag struct { Base int Action func(*Context, uint) error + // Has unexported fields. } UintFlag is a flag with type uint @@ -2219,6 +2230,7 @@ type UintSliceFlag struct { EnvVars []string Action func(*Context, []uint) error + // Has unexported fields. } UintSliceFlag is a flag with type *UintSlice diff --git a/vendor/github.com/urfave/cli/v2/help.go b/vendor/github.com/urfave/cli/v2/help.go index 6929a226a..466ff3479 100644 --- a/vendor/github.com/urfave/cli/v2/help.go +++ b/vendor/github.com/urfave/cli/v2/help.go @@ -68,6 +68,15 @@ var helpCommand = &Command{ } // Case 3, 5 + if (len(cCtx.Command.Subcommands) == 1 && !cCtx.Command.HideHelp) || + (len(cCtx.Command.Subcommands) == 0 && cCtx.Command.HideHelp) { + templ := cCtx.Command.CustomHelpTemplate + if templ == "" { + templ = CommandHelpTemplate + } + HelpPrinter(cCtx.App.Writer, templ, cCtx.Command) + return nil + } return ShowSubcommandHelp(cCtx) }, } @@ -230,13 +239,12 @@ func ShowCommandHelpAndExit(c *Context, command string, code int) { // ShowCommandHelp prints help for the given command func ShowCommandHelp(ctx *Context, command string) error { - // show the subcommand help for a command with subcommands - if command == "" { - HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App) - return nil - } - for _, c := range ctx.App.Commands { + commands := ctx.App.Commands + if ctx.Command.Subcommands != nil { + commands = ctx.Command.Subcommands + } + for _, c := range commands { if c.HasName(command) { if !ctx.App.HideHelpCommand && !c.HasName(helpName) && len(c.Subcommands) != 0 { c.Subcommands = append(c.Subcommands, helpCommandDontUse) @@ -262,7 +270,7 @@ func ShowCommandHelp(ctx *Context, command string) error { if ctx.App.CommandNotFound == nil { errMsg := fmt.Sprintf("No help topic for '%v'", command) if ctx.App.Suggest { - if suggestion := SuggestCommand(ctx.App.Commands, command); suggestion != "" { + if suggestion := SuggestCommand(ctx.Command.Subcommands, command); suggestion != "" { errMsg += ". " + suggestion } } @@ -285,11 +293,8 @@ func ShowSubcommandHelp(cCtx *Context) error { return nil } - if cCtx.Command != nil { - return ShowCommandHelp(cCtx, cCtx.Command.Name) - } - - return ShowCommandHelp(cCtx, "") + HelpPrinter(cCtx.App.Writer, SubcommandHelpTemplate, cCtx.Command) + return nil } // ShowVersion prints the version number of the App @@ -358,6 +363,17 @@ func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) + t.New("helpNameTemplate").Parse(helpNameTemplate) + t.New("usageTemplate").Parse(usageTemplate) + t.New("descriptionTemplate").Parse(descriptionTemplate) + t.New("visibleCommandTemplate").Parse(visibleCommandTemplate) + t.New("copyrightTemplate").Parse(copyrightTemplate) + t.New("versionTemplate").Parse(versionTemplate) + t.New("visibleFlagCategoryTemplate").Parse(visibleFlagCategoryTemplate) + t.New("visibleFlagTemplate").Parse(visibleFlagTemplate) + t.New("visibleGlobalFlagCategoryTemplate").Parse(strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1)) + t.New("authorsTemplate").Parse(authorsTemplate) + t.New("visibleCommandCategoryTemplate").Parse(visibleCommandCategoryTemplate) err := t.Execute(w, data) if err != nil { @@ -390,8 +406,10 @@ func checkHelp(cCtx *Context) bool { for _, name := range HelpFlag.Names() { if cCtx.Bool(name) { found = true + break } } + return found } diff --git a/vendor/github.com/urfave/cli/v2/parse.go b/vendor/github.com/urfave/cli/v2/parse.go index a2db306e1..d79f15a18 100644 --- a/vendor/github.com/urfave/cli/v2/parse.go +++ b/vendor/github.com/urfave/cli/v2/parse.go @@ -46,7 +46,10 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple } // swap current argument with the split version - args = append(args[:i], append(shortOpts, args[i+1:]...)...) + // do not include args that parsed correctly so far as it would + // trigger Value.Set() on those args and would result in + // duplicates for slice type flags + args = append(shortOpts, args[i+1:]...) argsWereSplit = true break } @@ -56,13 +59,6 @@ func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComple if !argsWereSplit { return err } - - // Since custom parsing failed, replace the flag set before retrying - newSet, err := ip.newFlagSet() - if err != nil { - return err - } - *set = *newSet } } diff --git a/vendor/github.com/urfave/cli/v2/template.go b/vendor/github.com/urfave/cli/v2/template.go index 9e13604f3..b565ba61e 100644 --- a/vendor/github.com/urfave/cli/v2/template.go +++ b/vendor/github.com/urfave/cli/v2/template.go @@ -1,10 +1,38 @@ package cli +var helpNameTemplate = `{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}` +var usageTemplate = `{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}` +var descriptionTemplate = `{{wrap .Description 3}}` +var authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: + {{range $index, $author := .Authors}}{{if $index}} + {{end}}{{$author}}{{end}}` +var visibleCommandTemplate = `{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}} + {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}` +var visibleCommandCategoryTemplate = `{{range .VisibleCategories}}{{if .Name}} + {{.Name}}:{{range .VisibleCommands}} + {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{template "visibleCommandTemplate" .}}{{end}}{{end}}` +var visibleFlagCategoryTemplate = `{{range .VisibleFlagCategories}} + {{if .Name}}{{.Name}} + + {{end}}{{$flglen := len .Flags}}{{range $i, $e := .Flags}}{{if eq (subtract $flglen $i) 1}}{{$e}} +{{else}}{{$e}} + {{end}}{{end}}{{end}}` + +var visibleFlagTemplate = `{{range $i, $e := .VisibleFlags}} + {{wrap $e.String 6}}{{end}}` + +var versionTemplate = `{{if .Version}}{{if not .HideVersion}} + +VERSION: + {{.Version}}{{end}}{{end}}` + +var copyrightTemplate = `{{wrap .Copyright 3}}` + // AppHelpTemplate is the text template for the Default help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var AppHelpTemplate = `NAME: - {{$v := offset .Name 6}}{{wrap .Name 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}} + {{template "helpNameTemplate" .}} USAGE: {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} @@ -13,72 +41,58 @@ VERSION: {{.Version}}{{end}}{{end}}{{if .Description}} DESCRIPTION: - {{wrap .Description 3}}{{end}}{{if len .Authors}} + {{template "descriptionTemplate" .}}{{end}} +{{- if len .Authors}} -AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: - {{range $index, $author := .Authors}}{{if $index}} - {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}} +AUTHOR{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}} -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}} - {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}} +COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}} -GLOBAL OPTIONS:{{range .VisibleFlagCategories}} - {{if .Name}}{{.Name}} - {{end}}{{range .Flags}}{{.}} - {{end}}{{end}}{{else}}{{if .VisibleFlags}} +GLOBAL OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} -GLOBAL OPTIONS: - {{range $index, $option := .VisibleFlags}}{{if $index}} - {{end}}{{wrap $option.String 6}}{{end}}{{end}}{{end}}{{if .Copyright}} +GLOBAL OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}} COPYRIGHT: - {{wrap .Copyright 3}}{{end}} + {{template "copyrightTemplate" .}}{{end}} ` // CommandHelpTemplate is the text template for the command help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var CommandHelpTemplate = `NAME: - {{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}} + {{template "helpNameTemplate" .}} USAGE: - {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}} + {{template "usageTemplate" .}}{{if .Category}} CATEGORY: {{.Category}}{{end}}{{if .Description}} DESCRIPTION: - {{wrap .Description 3}}{{end}}{{if .VisibleFlagCategories}} + {{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}} -OPTIONS:{{range .VisibleFlagCategories}} - {{if .Name}}{{.Name}} - {{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}} +OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} -OPTIONS: - {{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}} +OPTIONS:{{template "visibleFlagTemplate" .}}{{end}} ` // SubcommandHelpTemplate is the text template for the subcommand help topic. // cli.go uses text/template to render templates. You can // render custom help text by setting this variable. var SubcommandHelpTemplate = `NAME: - {{.HelpName}} - {{.Usage}} + {{template "helpNameTemplate" .}} USAGE: - {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} + {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} DESCRIPTION: - {{wrap .Description 3}}{{end}} + {{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}} -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}} - {{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} +COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}} -OPTIONS: - {{range .VisibleFlags}}{{.}}{{end}}{{end}} +OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} + +OPTIONS:{{template "visibleFlagTemplate" .}}{{end}} ` var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }} diff --git a/vendor/github.com/urfave/cli/v2/zz_generated.flags.go b/vendor/github.com/urfave/cli/v2/zz_generated.flags.go index 0309a2868..7d0a267f7 100644 --- a/vendor/github.com/urfave/cli/v2/zz_generated.flags.go +++ b/vendor/github.com/urfave/cli/v2/zz_generated.flags.go @@ -23,6 +23,8 @@ type Float64SliceFlag struct { Aliases []string EnvVars []string + defaultValue *Float64Slice + Action func(*Context, []float64) error } @@ -65,6 +67,8 @@ type GenericFlag struct { Aliases []string EnvVars []string + defaultValue Generic + TakesFile bool Action func(*Context, interface{}) error @@ -114,6 +118,8 @@ type Int64SliceFlag struct { Aliases []string EnvVars []string + defaultValue *Int64Slice + Action func(*Context, []int64) error } @@ -156,6 +162,8 @@ type IntSliceFlag struct { Aliases []string EnvVars []string + defaultValue *IntSlice + Action func(*Context, []int) error } @@ -198,6 +206,8 @@ type PathFlag struct { Aliases []string EnvVars []string + defaultValue Path + TakesFile bool Action func(*Context, Path) error @@ -247,6 +257,8 @@ type StringSliceFlag struct { Aliases []string EnvVars []string + defaultValue *StringSlice + TakesFile bool Action func(*Context, []string) error @@ -291,6 +303,8 @@ type TimestampFlag struct { Aliases []string EnvVars []string + defaultValue *Timestamp + Layout string Timezone *time.Location @@ -342,6 +356,8 @@ type Uint64SliceFlag struct { Aliases []string EnvVars []string + defaultValue *Uint64Slice + Action func(*Context, []uint64) error } @@ -384,6 +400,8 @@ type UintSliceFlag struct { Aliases []string EnvVars []string + defaultValue *UintSlice + Action func(*Context, []uint) error } @@ -426,6 +444,8 @@ type BoolFlag struct { Aliases []string EnvVars []string + defaultValue bool + Count *int Action func(*Context, bool) error @@ -475,6 +495,8 @@ type Float64Flag struct { Aliases []string EnvVars []string + defaultValue float64 + Action func(*Context, float64) error } @@ -522,6 +544,8 @@ type IntFlag struct { Aliases []string EnvVars []string + defaultValue int + Base int Action func(*Context, int) error @@ -571,6 +595,8 @@ type Int64Flag struct { Aliases []string EnvVars []string + defaultValue int64 + Base int Action func(*Context, int64) error @@ -620,6 +646,8 @@ type StringFlag struct { Aliases []string EnvVars []string + defaultValue string + TakesFile bool Action func(*Context, string) error @@ -669,6 +697,8 @@ type DurationFlag struct { Aliases []string EnvVars []string + defaultValue time.Duration + Action func(*Context, time.Duration) error } @@ -716,6 +746,8 @@ type UintFlag struct { Aliases []string EnvVars []string + defaultValue uint + Base int Action func(*Context, uint) error @@ -765,6 +797,8 @@ type Uint64Flag struct { Aliases []string EnvVars []string + defaultValue uint64 + Base int Action func(*Context, uint64) error diff --git a/vendor/github.com/status-im/go-discover/COPYING.LESSER b/vendor/github.com/waku-org/go-discover/COPYING.LESSER similarity index 100% rename from vendor/github.com/status-im/go-discover/COPYING.LESSER rename to vendor/github.com/waku-org/go-discover/COPYING.LESSER diff --git a/vendor/github.com/status-im/go-discover/discover/common.go b/vendor/github.com/waku-org/go-discover/discover/common.go similarity index 82% rename from vendor/github.com/status-im/go-discover/discover/common.go rename to vendor/github.com/waku-org/go-discover/discover/common.go index 44976be3e..b465ca84e 100644 --- a/vendor/github.com/status-im/go-discover/discover/common.go +++ b/vendor/github.com/waku-org/go-discover/discover/common.go @@ -25,7 +25,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/netutil" - "github.com/status-im/go-discover/discover/v5wire" + "github.com/waku-org/go-discover/discover/v5wire" ) // UDPConn is a network connection on which discovery can operate. @@ -37,7 +37,7 @@ type UDPConn interface { } type V5Config struct { - ProtocolID [6]byte + ProtocolID *[6]byte } // Config holds settings for the discovery listener. @@ -46,14 +46,14 @@ type Config struct { PrivateKey *ecdsa.PrivateKey // These settings are optional: - NetRestrict *netutil.Netlist // list of allowed IP networks - Bootnodes []*enode.Node // list of bootstrap nodes - Unhandled chan<- ReadPacket // unhandled packets are sent on this channel - Log log.Logger // if set, log messages go here - ValidSchemes enr.IdentityScheme // allowed identity schemes - Clock mclock.Clock - ValidNodeFn func(enode.Node) bool // function to validate a node before it's added to routing tables + NetRestrict *netutil.Netlist // list of allowed IP networks + Bootnodes []*enode.Node // list of bootstrap nodes + Unhandled chan<- ReadPacket // unhandled packets are sent on this channel + Log log.Logger // if set, log messages go here + ValidSchemes enr.IdentityScheme // allowed identity schemes V5Config V5Config // DiscV5 settings + ValidNodeFn func(enode.Node) bool // function to validate a node before it's added to routing tables + Clock mclock.Clock } func (cfg Config) withDefaults() Config { @@ -66,8 +66,8 @@ func (cfg Config) withDefaults() Config { if cfg.Clock == nil { cfg.Clock = mclock.System{} } - if len(cfg.V5Config.ProtocolID) == 0 { - cfg.V5Config.ProtocolID = v5wire.DefaultProtocolID + if cfg.V5Config.ProtocolID == nil { + cfg.V5Config.ProtocolID = &v5wire.DefaultProtocolID } return cfg } diff --git a/vendor/github.com/status-im/go-discover/discover/lookup.go b/vendor/github.com/waku-org/go-discover/discover/lookup.go similarity index 99% rename from vendor/github.com/status-im/go-discover/discover/lookup.go rename to vendor/github.com/waku-org/go-discover/discover/lookup.go index 9ab4a71ce..b8d97b44e 100644 --- a/vendor/github.com/status-im/go-discover/discover/lookup.go +++ b/vendor/github.com/waku-org/go-discover/discover/lookup.go @@ -18,6 +18,7 @@ package discover import ( "context" + "errors" "time" "github.com/ethereum/go-ethereum/p2p/enode" @@ -141,7 +142,7 @@ func (it *lookup) slowdown() { func (it *lookup) query(n *node, reply chan<- []*node) { fails := it.tab.db.FindFails(n.ID(), n.IP()) r, err := it.queryfunc(n) - if err == errClosed { + if errors.Is(err, errClosed) { // Avoid recording failures on shutdown. reply <- nil return diff --git a/vendor/github.com/status-im/go-discover/discover/node.go b/vendor/github.com/waku-org/go-discover/discover/node.go similarity index 100% rename from vendor/github.com/status-im/go-discover/discover/node.go rename to vendor/github.com/waku-org/go-discover/discover/node.go diff --git a/vendor/github.com/status-im/go-discover/discover/ntp.go b/vendor/github.com/waku-org/go-discover/discover/ntp.go similarity index 98% rename from vendor/github.com/status-im/go-discover/discover/ntp.go rename to vendor/github.com/waku-org/go-discover/discover/ntp.go index 1bb52399f..48ceffe95 100644 --- a/vendor/github.com/status-im/go-discover/discover/ntp.go +++ b/vendor/github.com/waku-org/go-discover/discover/ntp.go @@ -108,7 +108,7 @@ func sntpDrift(measurements int) (time.Duration, error) { // Calculate the drift based on an assumed answer time of RRT/2 drifts = append(drifts, sent.Sub(t)+elapsed/2) } - // Calculate average drif (drop two extremities to avoid outliers) + // Calculate average drift (drop two extremities to avoid outliers) sort.Sort(durationSlice(drifts)) drift := time.Duration(0) diff --git a/vendor/github.com/status-im/go-discover/discover/table.go b/vendor/github.com/waku-org/go-discover/discover/table.go similarity index 99% rename from vendor/github.com/status-im/go-discover/discover/table.go rename to vendor/github.com/waku-org/go-discover/discover/table.go index f721bcbad..c91b8b856 100644 --- a/vendor/github.com/status-im/go-discover/discover/table.go +++ b/vendor/github.com/waku-org/go-discover/discover/table.go @@ -458,7 +458,6 @@ func (tab *Table) bucketAtDistance(d int) *bucket { return tab.buckets[d-bucketMinDistance-1] } -///////////////////////////////////////////////////////////////////////////////////////////////////////// // addSeenNode adds a node which may or may not be live to the end of a bucket. If the // bucket has space available, adding the node succeeds immediately. Otherwise, the node is // added to the replacements list. @@ -498,7 +497,6 @@ func (tab *Table) addSeenNode(n *node) { } } -///////////////////////////////////////////////////////////// // addVerifiedNode adds a node whose existence has been verified recently to the front of a // bucket. If the node is already in the bucket, it is moved to the front. If the bucket // has no space, the node is added to the replacements list. diff --git a/vendor/github.com/status-im/go-discover/discover/v4_udp.go b/vendor/github.com/waku-org/go-discover/discover/v4_udp.go similarity index 98% rename from vendor/github.com/status-im/go-discover/discover/v4_udp.go rename to vendor/github.com/waku-org/go-discover/discover/v4_udp.go index 095006cff..00988c526 100644 --- a/vendor/github.com/status-im/go-discover/discover/v4_udp.go +++ b/vendor/github.com/waku-org/go-discover/discover/v4_udp.go @@ -33,7 +33,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/netutil" - "github.com/status-im/go-discover/discover/v4wire" + "github.com/waku-org/go-discover/discover/v4wire" ) // Errors @@ -328,13 +328,13 @@ func (t *UDPv4) findnode(toid enode.ID, toaddr *net.UDPAddr, target v4wire.Pubke // enough nodes the reply matcher will time out waiting for the second reply, but // there's no need for an error in that case. err := <-rm.errc - if err == errTimeout && rm.reply != nil { + if errors.Is(err, errTimeout) && rm.reply != nil { err = nil } return nodes, err } -// RequestENR sends enrRequest to the given node and waits for a response. +// RequestENR sends ENRRequest to the given node and waits for a response. func (t *UDPv4) RequestENR(n *enode.Node) (*enode.Node, error) { addr := &net.UDPAddr{IP: n.IP(), Port: n.UDP()} t.ensureBond(n.ID(), addr) @@ -525,8 +525,8 @@ func (t *UDPv4) readLoop(unhandled chan<- ReadPacket) { t.log.Debug("Temporary UDP read error", "err", err) continue } else if err != nil { - // Shut down the loop for permament errors. - if err != io.EOF { + // Shut down the loop for permanent errors. + if !errors.Is(err, io.EOF) { t.log.Debug("UDP read error", "err", err) } return diff --git a/vendor/github.com/status-im/go-discover/discover/v4wire/v4wire.go b/vendor/github.com/waku-org/go-discover/discover/v4wire/v4wire.go similarity index 95% rename from vendor/github.com/status-im/go-discover/discover/v4wire/v4wire.go rename to vendor/github.com/waku-org/go-discover/discover/v4wire/v4wire.go index bc537a4cf..3935068cd 100644 --- a/vendor/github.com/status-im/go-discover/discover/v4wire/v4wire.go +++ b/vendor/github.com/waku-org/go-discover/discover/v4wire/v4wire.go @@ -1,4 +1,4 @@ -// Copyright 2019 The go-ethereum Authors +// Copyright 2020 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -60,7 +60,7 @@ type ( Pong struct { // This field should mirror the UDP envelope address // of the ping packet, which provides a way to discover the - // the external address (after NAT). + // external address (after NAT). To Endpoint ReplyTok []byte // This contains the hash of the ping packet. Expiration uint64 // Absolute timestamp at which the packet becomes invalid. @@ -86,23 +86,23 @@ type ( Rest []rlp.RawValue `rlp:"tail"` } - // enrRequest queries for the remote node's record. + // ENRRequest queries for the remote node's record. ENRRequest struct { Expiration uint64 // Ignore additional fields (for forward compatibility). Rest []rlp.RawValue `rlp:"tail"` } - // enrResponse is the reply to enrRequest. + // ENRResponse is the reply to ENRRequest. ENRResponse struct { - ReplyTok []byte // Hash of the enrRequest packet. + ReplyTok []byte // Hash of the ENRRequest packet. Record enr.Record // Ignore additional fields (for forward compatibility). Rest []rlp.RawValue `rlp:"tail"` } ) -// This number is the maximum number of neighbor nodes in a Neighbors packet. +// MaxNeighbors is the maximum number of neighbor nodes in a Neighbors packet. const MaxNeighbors = 12 // This code computes the MaxNeighbors constant value. @@ -161,8 +161,9 @@ func NewEndpoint(addr *net.UDPAddr, tcpPort uint16) Endpoint { } type Packet interface { - // packet name and type for logging purposes. + // Name is the name of the package, for logging purposes. Name() string + // Kind is the packet type, for logging purposes. Kind() byte } diff --git a/vendor/github.com/status-im/go-discover/discover/v5_udp.go b/vendor/github.com/waku-org/go-discover/discover/v5_udp.go similarity index 98% rename from vendor/github.com/status-im/go-discover/discover/v5_udp.go rename to vendor/github.com/waku-org/go-discover/discover/v5_udp.go index 167d4de86..d4e6a2e5a 100644 --- a/vendor/github.com/status-im/go-discover/discover/v5_udp.go +++ b/vendor/github.com/waku-org/go-discover/discover/v5_udp.go @@ -1,4 +1,4 @@ -// Copyright 2019 The go-ethereum Authors +// Copyright 2020 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -34,7 +34,7 @@ import ( "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/p2p/netutil" - "github.com/status-im/go-discover/discover/v5wire" + "github.com/waku-org/go-discover/discover/v5wire" ) const ( @@ -54,7 +54,7 @@ type codecV5 interface { // Encode encodes a packet. Encode(enode.ID, string, v5wire.Packet, *v5wire.Whoareyou) ([]byte, v5wire.Nonce, error) - // decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails. + // Decode decodes a packet. It returns a *v5wire.Unknown packet if decryption fails. // The *enode.Node return value is non-nil when the input contains a handshake response. Decode([]byte, string) (enode.ID, *enode.Node, v5wire.Packet, error) } @@ -156,7 +156,7 @@ func newUDPv5(conn UDPConn, ln *enode.LocalNode, cfg Config) (*UDPv5, error) { callDoneCh: make(chan *callV5), respTimeoutCh: make(chan *callTimeout), // state of dispatch - codec: v5wire.NewCodec(ln, cfg.PrivateKey, cfg.Clock, cfg.V5Config.ProtocolID), + codec: v5wire.NewCodec(ln, cfg.PrivateKey, cfg.Clock, *cfg.V5Config.ProtocolID), activeCallByNode: make(map[enode.ID]*callV5), activeCallByAuth: make(map[v5wire.Nonce]*callV5), callQueue: make(map[enode.ID][]*callV5), @@ -305,7 +305,7 @@ func (t *UDPv5) lookupWorker(destNode *node, target enode.ID) ([]*node, error) { ) var r []*enode.Node r, err = t.findnode(unwrapNode(destNode), dists) - if err == errClosed { + if errors.Is(err, errClosed) { return nil, err } for _, n := range r { @@ -347,7 +347,7 @@ func (t *UDPv5) ping(n *enode.Node) (uint64, error) { } } -// requestENR requests n's record. +// RequestENR requests n's record. func (t *UDPv5) RequestENR(n *enode.Node) (*enode.Node, error) { nodes, err := t.findnode(n, []uint{0}) if err != nil { @@ -407,6 +407,9 @@ func (t *UDPv5) verifyResponseNode(c *callV5, r *enr.Record, distances []uint, s if err := netutil.CheckRelayIP(c.node.IP(), node.IP()); err != nil { return nil, err } + if t.netrestrict != nil && !t.netrestrict.Contains(node.IP()) { + return nil, errors.New("not contained in netrestrict list") + } if c.node.UDP() <= 1024 { return nil, errLowPort } @@ -622,8 +625,8 @@ func (t *UDPv5) readLoop() { t.log.Debug("Temporary UDP read error", "err", err) continue } else if err != nil { - // Shut down the loop for permament errors. - if err != io.EOF { + // Shut down the loop for permanent errors. + if !errors.Is(err, io.EOF) { t.log.Debug("UDP read error", "err", err) } return diff --git a/vendor/github.com/status-im/go-discover/discover/v5wire/crypto.go b/vendor/github.com/waku-org/go-discover/discover/v5wire/crypto.go similarity index 100% rename from vendor/github.com/status-im/go-discover/discover/v5wire/crypto.go rename to vendor/github.com/waku-org/go-discover/discover/v5wire/crypto.go diff --git a/vendor/github.com/status-im/go-discover/discover/v5wire/encoding.go b/vendor/github.com/waku-org/go-discover/discover/v5wire/encoding.go similarity index 96% rename from vendor/github.com/status-im/go-discover/discover/v5wire/encoding.go rename to vendor/github.com/waku-org/go-discover/discover/v5wire/encoding.go index ea89492ba..47e8dcd91 100644 --- a/vendor/github.com/status-im/go-discover/discover/v5wire/encoding.go +++ b/vendor/github.com/waku-org/go-discover/discover/v5wire/encoding.go @@ -1,4 +1,4 @@ -// Copyright 2019 The go-ethereum Authors +// Copyright 2020 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -90,6 +90,10 @@ const ( minVersion = 1 sizeofMaskingIV = 16 + // The minimum size of any Discovery v5 packet is 63 bytes. + // Should reject packets smaller than minPacketSize. + minPacketSize = 63 + minMessageSize = 48 // this refers to data after static headers randomPacketMsgSize = 20 ) @@ -114,6 +118,7 @@ var ( // Public errors. var ( + // ErrInvalidReqID represents error when the ID is invalid. ErrInvalidReqID = errors.New("request ID larger than 8 bytes") ) @@ -129,11 +134,10 @@ var ( // Codec encodes and decodes Discovery v5 packets. // This type is not safe for concurrent use. type Codec struct { - sha256 hash.Hash - localnode *enode.LocalNode - privkey *ecdsa.PrivateKey - sc *SessionCache - + sha256 hash.Hash + localnode *enode.LocalNode + privkey *ecdsa.PrivateKey + sc *SessionCache protocolID [6]byte // encoder buffers @@ -303,7 +307,7 @@ func (c *Codec) encodeWhoareyou(toID enode.ID, packet *Whoareyou) (Header, error return head, nil } -// encodeHandshakeMessage encodes the handshake message packet header. +// encodeHandshakeHeader encodes the handshake message packet header. func (c *Codec) encodeHandshakeHeader(toID enode.ID, addr string, challenge *Whoareyou) (Header, *session, error) { // Ensure calling code sets challenge.node. if challenge.Node == nil { @@ -340,7 +344,7 @@ func (c *Codec) encodeHandshakeHeader(toID enode.ID, addr string, challenge *Who return head, session, err } -// encodeAuthHeader creates the auth header on a request packet following WHOAREYOU. +// makeHandshakeAuth creates the auth header on a request packet following WHOAREYOU. func (c *Codec) makeHandshakeAuth(toID enode.ID, addr string, challenge *Whoareyou) (*handshakeAuthData, *session, error) { auth := new(handshakeAuthData) auth.h.SrcID = c.localnode.ID() @@ -382,7 +386,7 @@ func (c *Codec) makeHandshakeAuth(toID enode.ID, addr string, challenge *Whoarey return auth, sec, err } -// encodeMessage encodes an encrypted message packet. +// encodeMessageHeader encodes an encrypted message packet. func (c *Codec) encodeMessageHeader(toID enode.ID, s *session) (Header, error) { head := c.makeHeader(toID, flagMessage, 0) @@ -418,10 +422,10 @@ func (c *Codec) encryptMessage(s *session, p Packet, head *Header, headerData [] // Decode decodes a discovery packet. func (c *Codec) Decode(input []byte, addr string) (src enode.ID, n *enode.Node, p Packet, err error) { - // Unmask the static header. - if len(input) < sizeofStaticPacketData { + if len(input) < minPacketSize { return enode.ID{}, nil, nil, errTooShort } + // Unmask the static header. var head Header copy(head.IV[:], input[:sizeofMaskingIV]) mask := head.mask(c.localnode.ID()) @@ -599,7 +603,7 @@ func (c *Codec) decodeMessage(fromAddr string, head *Header, headerData, msgData // Try decrypting the message. key := c.sc.readKey(auth.SrcID, fromAddr) msg, err := c.decryptMessage(msgData, head.Nonce[:], headerData, key) - if err == errMessageDecrypt { + if errors.Is(err, errMessageDecrypt) { // It didn't work. Start the handshake since this is an ordinary message packet. return &Unknown{Nonce: head.Nonce}, nil } @@ -635,7 +639,7 @@ func (h *StaticHeader) checkValid(packetLen int, protocolID [6]byte) error { return nil } -// headerMask returns a cipher for 'masking' / 'unmasking' packet headers. +// mask returns a cipher for 'masking' / 'unmasking' packet headers. func (h *Header) mask(destID enode.ID) cipher.Stream { block, err := aes.NewCipher(destID[:16]) if err != nil { diff --git a/vendor/github.com/status-im/go-discover/discover/v5wire/msg.go b/vendor/github.com/waku-org/go-discover/discover/v5wire/msg.go similarity index 91% rename from vendor/github.com/status-im/go-discover/discover/v5wire/msg.go rename to vendor/github.com/waku-org/go-discover/discover/v5wire/msg.go index c04966847..1316598a4 100644 --- a/vendor/github.com/status-im/go-discover/discover/v5wire/msg.go +++ b/vendor/github.com/waku-org/go-discover/discover/v5wire/msg.go @@ -1,4 +1,4 @@ -// Copyright 2019 The go-ethereum Authors +// Copyright 2020 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -59,7 +59,7 @@ type ( Nonce Nonce } - // WHOAREYOU contains the handshake challenge. + // Whoareyou contains the handshake challenge. Whoareyou struct { ChallengeData []byte // Encoded challenge Nonce Nonce // Nonce of request packet @@ -73,13 +73,13 @@ type ( sent mclock.AbsTime // for handshake GC. } - // PING is sent during liveness checks. + // Ping is sent during liveness checks. Ping struct { ReqID []byte ENRSeq uint64 } - // PONG is the reply to PING. + // Pong is the reply to Ping. Pong struct { ReqID []byte ENRSeq uint64 @@ -87,58 +87,58 @@ type ( ToPort uint16 // packet, which provides a way to discover the external address (after NAT). } - // FINDNODE is a query for nodes in the given bucket. + // Findnode is a query for nodes in the given bucket. Findnode struct { ReqID []byte Distances []uint } - // NODES is the reply to FINDNODE and TOPICQUERY. + // Nodes is the reply to Findnode and Topicquery. Nodes struct { ReqID []byte Total uint8 Nodes []*enr.Record } - // TALKREQ is an application-level request. + // TalkRequest is an application-level request. TalkRequest struct { ReqID []byte Protocol string Message []byte } - // TALKRESP is the reply to TALKREQ. + // TalkResponse is the reply to TalkRequest. TalkResponse struct { ReqID []byte Message []byte } - // REQUESTTICKET requests a ticket for a topic queue. + // RequestTicket requests a ticket for a topic queue. RequestTicket struct { ReqID []byte Topic []byte } - // TICKET is the response to REQUESTTICKET. + // Ticket is the response to RequestTicket. Ticket struct { ReqID []byte Ticket []byte } - // REGTOPIC registers the sender in a topic queue using a ticket. + // Regtopic registers the sender in a topic queue using a ticket. Regtopic struct { ReqID []byte Ticket []byte ENR *enr.Record } - // REGCONFIRMATION is the reply to REGTOPIC. + // Regconfirmation is the reply to Regtopic. Regconfirmation struct { ReqID []byte Registered bool } - // TOPICQUERY asks for nodes with the given topic. + // TopicQuery asks for nodes with the given topic. TopicQuery struct { ReqID []byte Topic []byte diff --git a/vendor/github.com/status-im/go-discover/discover/v5wire/session.go b/vendor/github.com/waku-org/go-discover/discover/v5wire/session.go similarity index 100% rename from vendor/github.com/status-im/go-discover/discover/v5wire/session.go rename to vendor/github.com/waku-org/go-discover/discover/v5wire/session.go diff --git a/vendor/github.com/status-im/go-zerokit-rln/LICENSE b/vendor/github.com/waku-org/go-zerokit-rln/LICENSE similarity index 100% rename from vendor/github.com/status-im/go-zerokit-rln/LICENSE rename to vendor/github.com/waku-org/go-zerokit-rln/LICENSE diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/librln.h b/vendor/github.com/waku-org/go-zerokit-rln/rln/librln.h similarity index 90% rename from vendor/github.com/status-im/go-zerokit-rln/rln/librln.h rename to vendor/github.com/waku-org/go-zerokit-rln/rln/librln.h index cf1f017df..f806475ad 100644 --- a/vendor/github.com/status-im/go-zerokit-rln/rln/librln.h +++ b/vendor/github.com/waku-org/go-zerokit-rln/rln/librln.h @@ -52,6 +52,11 @@ bool verify_rln_proof(const struct RLN *ctx, const struct Buffer *proof_buffer, bool *proof_is_valid_ptr); +bool verify_with_roots(const struct RLN *ctx, + const struct Buffer *proof_buffer, + const struct Buffer *roots_buffer, + bool *proof_is_valid_ptr); + bool key_gen(const struct RLN *ctx, struct Buffer *output_buffer); bool seeded_key_gen(const struct RLN *ctx, diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/link.go b/vendor/github.com/waku-org/go-zerokit-rln/rln/link.go similarity index 100% rename from vendor/github.com/status-im/go-zerokit-rln/rln/link.go rename to vendor/github.com/waku-org/go-zerokit-rln/rln/link.go diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/resources/bindata.go b/vendor/github.com/waku-org/go-zerokit-rln/rln/resources/bindata.go similarity index 100% rename from vendor/github.com/status-im/go-zerokit-rln/rln/resources/bindata.go rename to vendor/github.com/waku-org/go-zerokit-rln/rln/resources/bindata.go diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/resources/doc.go b/vendor/github.com/waku-org/go-zerokit-rln/rln/resources/doc.go similarity index 100% rename from vendor/github.com/status-im/go-zerokit-rln/rln/resources/doc.go rename to vendor/github.com/waku-org/go-zerokit-rln/rln/resources/doc.go diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/rln.go b/vendor/github.com/waku-org/go-zerokit-rln/rln/rln.go similarity index 92% rename from vendor/github.com/status-im/go-zerokit-rln/rln/rln.go rename to vendor/github.com/waku-org/go-zerokit-rln/rln/rln.go index a097a086c..06e761dfd 100644 --- a/vendor/github.com/status-im/go-zerokit-rln/rln/rln.go +++ b/vendor/github.com/waku-org/go-zerokit-rln/rln/rln.go @@ -9,7 +9,7 @@ import ( "errors" "unsafe" - "github.com/status-im/go-zerokit-rln/rln/resources" + "github.com/waku-org/go-zerokit-rln/rln/resources" ) // RLN represents the context used for rln. @@ -221,15 +221,38 @@ func (r *RLN) GenerateProof(data []byte, key MembershipKeyPair, index Membership // Verify verifies a proof generated for the RLN. // proof [ proof<128>| root<32>| epoch<32>| share_x<32>| share_y<32>| nullifier<32> | signal_len<8> | signal ] -func (r *RLN) Verify(data []byte, proof RateLimitProof) bool { +func (r *RLN) Verify(data []byte, proof RateLimitProof) (bool, error) { proofBytes := proof.serialize(data) proofBuf := toCBufferPtr(proofBytes) res := C.bool(false) if !bool(C.verify_rln_proof(r.ptr, proofBuf, &res)) { - return false + return false, errors.New("could not verify rln proof") } - return bool(res) + return bool(res), nil +} + +func serializeRoots(roots [][32]byte) []byte { + var result []byte + for _, r := range roots { + result = append(result, r[:]...) + } + return result +} + +func (r *RLN) VerifyWithRoots(data []byte, proof RateLimitProof, roots [][32]byte) (bool, error) { + proofBytes := proof.serialize(data) + proofBuf := toCBufferPtr(proofBytes) + + rootBytes := serializeRoots(roots) + rootBuf := toCBufferPtr(rootBytes) + + res := C.bool(false) + if !bool(C.verify_with_roots(r.ptr, proofBuf, rootBuf, &res)) { + return false, errors.New("could not verify with roots") + } + + return bool(res), nil } // InsertMember adds the member to the tree diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/serialize.go b/vendor/github.com/waku-org/go-zerokit-rln/rln/serialize.go similarity index 100% rename from vendor/github.com/status-im/go-zerokit-rln/rln/serialize.go rename to vendor/github.com/waku-org/go-zerokit-rln/rln/serialize.go diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/types.go b/vendor/github.com/waku-org/go-zerokit-rln/rln/types.go similarity index 95% rename from vendor/github.com/status-im/go-zerokit-rln/rln/types.go rename to vendor/github.com/waku-org/go-zerokit-rln/rln/types.go index 8240f8c94..073dafa55 100644 --- a/vendor/github.com/status-im/go-zerokit-rln/rln/types.go +++ b/vendor/github.com/waku-org/go-zerokit-rln/rln/types.go @@ -26,32 +26,32 @@ type ZKSNARK = [128]byte type MembershipKeyPair = struct { // user's identity key (a secret key) which is selected randomly // see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership - IDKey IDKey + IDKey IDKey `json:"idKey"` // hash of user's identity key generated by // Poseidon hash function implemented in rln lib // more details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Membership - IDCommitment IDCommitment + IDCommitment IDCommitment `json:"idCommitment"` } type RateLimitProof struct { // RateLimitProof holds the public inputs to rln circuit as // defined in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Public-Inputs // the `proof` field carries the actual zkSNARK proof - Proof ZKSNARK + Proof ZKSNARK `json:"proof"` // the root of Merkle tree used for the generation of the `proof` - MerkleRoot MerkleNode + MerkleRoot MerkleNode `json:"root"` // the epoch used for the generation of the `proof` - Epoch Epoch + Epoch Epoch `json:"epoch"` // shareX and shareY are shares of user's identity key // these shares are created using Shamir secret sharing scheme // see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Linear-Equation-amp-SSS - ShareX MerkleNode - ShareY MerkleNode + ShareX MerkleNode `json:"share_x"` + ShareY MerkleNode `json:"share_y"` // nullifier enables linking two messages published during the same epoch // see details in https://hackmd.io/tMTLMYmTR5eynw2lwK9n1w?view#Nullifiers - Nullifier Nullifier + Nullifier Nullifier `json:"nullifier"` // Application specific RLN Identifier - RLNIdentifier RLNIdentifier + RLNIdentifier RLNIdentifier `json:"rlnIdentifier"` } type MembershipIndex = uint @@ -66,7 +66,7 @@ func (p ProofMetadata) Equals(p2 ProofMetadata) bool { return bytes.Equal(p.Nullifier[:], p2.Nullifier[:]) && bytes.Equal(p.ShareX[:], p2.ShareX[:]) && bytes.Equal(p.ShareY[:], p2.ShareY[:]) } -// the current implementation of the rln lib only supports a circuit for Merkle tree with depth 32 +// the current implementation of the rln lib only supports a circuit for Merkle tree with depth 32 const MERKLE_TREE_DEPTH int = 20 // HASH_BIT_SIZE is the size of poseidon hash output in bits @@ -80,9 +80,10 @@ const HASH_HEX_SIZE = int(HASH_BIT_SIZE / 8) const STATIC_GROUP_SIZE = 100 // STATIC_GROUP_KEYS is a static list of 100 membership keys in the form of (identity key, identity commitment) -// keys are created locally, using createMembershipList proc from waku_rln_relay_utils module, and the results are hardcoded in here -// this list is temporary and is created to test the performance of waku-rln-relay for the static groups -// in the later versions, this static hardcoded group will be replaced with a dynamic one +// +// keys are created locally, using createMembershipList proc from waku_rln_relay_utils module, and the results are hardcoded in here +// this list is temporary and is created to test the performance of waku-rln-relay for the static groups +// in the later versions, this static hardcoded group will be replaced with a dynamic one var STATIC_GROUP_KEYS [][]string func init() { diff --git a/vendor/github.com/status-im/go-zerokit-rln/rln/utils.go b/vendor/github.com/waku-org/go-zerokit-rln/rln/utils.go similarity index 100% rename from vendor/github.com/status-im/go-zerokit-rln/rln/utils.go rename to vendor/github.com/waku-org/go-zerokit-rln/rln/utils.go diff --git a/vendor/github.com/waku-org/noise/CONTRIBUTING.md b/vendor/github.com/waku-org/noise/CONTRIBUTING.md new file mode 100644 index 000000000..71b39ce26 --- /dev/null +++ b/vendor/github.com/waku-org/noise/CONTRIBUTING.md @@ -0,0 +1 @@ +See the [Flynn contributing guide](https://flynn.io/docs/contributing). diff --git a/vendor/github.com/marten-seemann/qtls-go1-17/LICENSE b/vendor/github.com/waku-org/noise/LICENSE similarity index 88% rename from vendor/github.com/marten-seemann/qtls-go1-17/LICENSE rename to vendor/github.com/waku-org/noise/LICENSE index 6a66aea5e..c1398eb3e 100644 --- a/vendor/github.com/marten-seemann/qtls-go1-17/LICENSE +++ b/vendor/github.com/waku-org/noise/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Flynn® is a trademark of Prime Directive, Inc. + +Copyright (c) 2015 Prime Directive, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -10,7 +12,7 @@ notice, this list of conditions and the following disclaimer. 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 + * Neither the name of Prime Directive, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/vendor/github.com/waku-org/noise/README.md b/vendor/github.com/waku-org/noise/README.md new file mode 100644 index 000000000..018fa7894 --- /dev/null +++ b/vendor/github.com/waku-org/noise/README.md @@ -0,0 +1,5 @@ +# noise [![Go Reference](https://pkg.go.dev/badge/github.com/flynn/noise.svg)](https://pkg.go.dev/github.com/flynn/noise) [![CI Status](https://github.com/flynn/noise/actions/workflows/ci.yml/badge.svg)](https://github.com/flynn/noise/actions) + +This is a Go package that implements the [Noise Protocol +Framework](https://noiseprotocol.org). See [the +documentation](https://pkg.go.dev/github.com/flynn/noise) for usage information. diff --git a/vendor/github.com/waku-org/noise/cipher_suite.go b/vendor/github.com/waku-org/noise/cipher_suite.go new file mode 100644 index 000000000..753e011f6 --- /dev/null +++ b/vendor/github.com/waku-org/noise/cipher_suite.go @@ -0,0 +1,224 @@ +package noise + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha256" + "crypto/sha512" + "encoding/binary" + "hash" + "io" + + "golang.org/x/crypto/blake2b" + "golang.org/x/crypto/blake2s" + "golang.org/x/crypto/chacha20poly1305" + "golang.org/x/crypto/curve25519" +) + +// A DHKey is a keypair used for Diffie-Hellman key agreement. +type DHKey struct { + Private []byte + Public []byte +} + +// A DHFunc implements Diffie-Hellman key agreement. +type DHFunc interface { + // GenerateKeypair generates a new keypair using random as a source of + // entropy. + GenerateKeypair(random io.Reader) (DHKey, error) + + // DH performs a Diffie-Hellman calculation between the provided private and + // public keys and returns the result. + DH(privkey, pubkey []byte) ([]byte, error) + + // DHLen is the number of bytes returned by DH. + DHLen() int + + // DHName is the name of the DH function. + DHName() string +} + +// A HashFunc implements a cryptographic hash function. +type HashFunc interface { + // Hash returns a hash state. + Hash() hash.Hash + + // HashName is the name of the hash function. + HashName() string +} + +// A CipherFunc implements an AEAD symmetric cipher. +type CipherFunc interface { + // Cipher initializes the algorithm with the provided key and returns a Cipher. + Cipher(k [32]byte) Cipher + + // CipherName is the name of the cipher. + CipherName() string +} + +// A Cipher is a AEAD cipher that has been initialized with a key. +type Cipher interface { + // Encrypt encrypts the provided plaintext with a nonce and then appends the + // ciphertext to out along with an authentication tag over the ciphertext + // and optional authenticated data. + Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte + + // Decrypt authenticates the ciphertext and optional authenticated data and + // then decrypts the provided ciphertext using the provided nonce and + // appends it to out. + Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error) +} + +// A CipherSuite is a set of cryptographic primitives used in a Noise protocol. +// It should be constructed with NewCipherSuite. +type CipherSuite interface { + DHFunc + CipherFunc + HashFunc + Name() []byte +} + +// NewCipherSuite returns a CipherSuite constructed from the specified +// primitives. +func NewCipherSuite(dh DHFunc, c CipherFunc, h HashFunc) CipherSuite { + return ciphersuite{ + DHFunc: dh, + CipherFunc: c, + HashFunc: h, + name: []byte(dh.DHName() + "_" + c.CipherName() + "_" + h.HashName()), + } +} + +type ciphersuite struct { + DHFunc + CipherFunc + HashFunc + name []byte +} + +func (s ciphersuite) Name() []byte { return s.name } + +// DH25519 is the Curve25519 ECDH function. +var DH25519 DHFunc = dh25519{} + +type dh25519 struct{} + +func (dh25519) GenerateKeypair(rng io.Reader) (DHKey, error) { + privkey := make([]byte, 32) + if rng == nil { + rng = rand.Reader + } + if _, err := io.ReadFull(rng, privkey); err != nil { + return DHKey{}, err + } + pubkey, err := curve25519.X25519(privkey, curve25519.Basepoint) + if err != nil { + return DHKey{}, err + } + return DHKey{Private: privkey, Public: pubkey}, nil +} + +func (dh25519) DH(privkey, pubkey []byte) ([]byte, error) { + return curve25519.X25519(privkey, pubkey) +} + +func (dh25519) DHLen() int { return 32 } +func (dh25519) DHName() string { return "25519" } + +type cipherFn struct { + fn func([32]byte) Cipher + name string +} + +func (c cipherFn) Cipher(k [32]byte) Cipher { return c.fn(k) } +func (c cipherFn) CipherName() string { return c.name } + +// CipherAESGCM is the AES256-GCM AEAD cipher. +var CipherAESGCM CipherFunc = cipherFn{cipherAESGCM, "AESGCM"} + +func cipherAESGCM(k [32]byte) Cipher { + c, err := aes.NewCipher(k[:]) + if err != nil { + panic(err) + } + gcm, err := cipher.NewGCM(c) + if err != nil { + panic(err) + } + return aeadCipher{ + gcm, + func(n uint64) []byte { + var nonce [12]byte + binary.BigEndian.PutUint64(nonce[4:], n) + return nonce[:] + }, + } +} + +// CipherChaChaPoly is the ChaCha20-Poly1305 AEAD cipher construction. +var CipherChaChaPoly CipherFunc = cipherFn{cipherChaChaPoly, "ChaChaPoly"} + +func cipherChaChaPoly(k [32]byte) Cipher { + c, err := chacha20poly1305.New(k[:]) + if err != nil { + panic(err) + } + return aeadCipher{ + c, + func(n uint64) []byte { + var nonce [12]byte + binary.LittleEndian.PutUint64(nonce[4:], n) + return nonce[:] + }, + } +} + +type aeadCipher struct { + cipher.AEAD + nonce func(uint64) []byte +} + +func (c aeadCipher) Encrypt(out []byte, n uint64, ad, plaintext []byte) []byte { + return c.Seal(out, c.nonce(n), plaintext, ad) +} + +func (c aeadCipher) Decrypt(out []byte, n uint64, ad, ciphertext []byte) ([]byte, error) { + return c.Open(out, c.nonce(n), ciphertext, ad) +} + +type hashFn struct { + fn func() hash.Hash + name string +} + +func (h hashFn) Hash() hash.Hash { return h.fn() } +func (h hashFn) HashName() string { return h.name } + +// HashSHA256 is the SHA-256 hash function. +var HashSHA256 HashFunc = hashFn{sha256.New, "SHA256"} + +// HashSHA512 is the SHA-512 hash function. +var HashSHA512 HashFunc = hashFn{sha512.New, "SHA512"} + +func blake2bNew() hash.Hash { + h, err := blake2b.New512(nil) + if err != nil { + panic(err) + } + return h +} + +// HashBLAKE2b is the BLAKE2b hash function. +var HashBLAKE2b HashFunc = hashFn{blake2bNew, "BLAKE2b"} + +func blake2sNew() hash.Hash { + h, err := blake2s.New256(nil) + if err != nil { + panic(err) + } + return h +} + +// HashBLAKE2s is the BLAKE2s hash function. +var HashBLAKE2s HashFunc = hashFn{blake2sNew, "BLAKE2s"} diff --git a/vendor/github.com/waku-org/noise/hkdf.go b/vendor/github.com/waku-org/noise/hkdf.go new file mode 100644 index 000000000..2ea494f5f --- /dev/null +++ b/vendor/github.com/waku-org/noise/hkdf.go @@ -0,0 +1,49 @@ +package noise + +import ( + "crypto/hmac" + "hash" +) + +func hkdf(h func() hash.Hash, outputs int, out1, out2, out3, chainingKey, inputKeyMaterial []byte) ([]byte, []byte, []byte) { + if len(out1) > 0 { + panic("len(out1) > 0") + } + if len(out2) > 0 { + panic("len(out2) > 0") + } + if len(out3) > 0 { + panic("len(out3) > 0") + } + if outputs > 3 { + panic("outputs > 3") + } + + tempMAC := hmac.New(h, chainingKey) + tempMAC.Write(inputKeyMaterial) + tempKey := tempMAC.Sum(out2) + + out1MAC := hmac.New(h, tempKey) + out1MAC.Write([]byte{0x01}) + out1 = out1MAC.Sum(out1) + + if outputs == 1 { + return out1, nil, nil + } + + out2MAC := hmac.New(h, tempKey) + out2MAC.Write(out1) + out2MAC.Write([]byte{0x02}) + out2 = out2MAC.Sum(out2) + + if outputs == 2 { + return out1, out2, nil + } + + out3MAC := hmac.New(h, tempKey) + out3MAC.Write(out2) + out3MAC.Write([]byte{0x03}) + out3 = out3MAC.Sum(out3) + + return out1, out2, out3 +} diff --git a/vendor/github.com/waku-org/noise/patterns.go b/vendor/github.com/waku-org/noise/patterns.go new file mode 100644 index 000000000..7d29d5ba7 --- /dev/null +++ b/vendor/github.com/waku-org/noise/patterns.go @@ -0,0 +1,141 @@ +package noise + +var HandshakeNN = HandshakePattern{ + Name: "NN", + Messages: [][]MessagePattern{ + {MessagePatternE}, + {MessagePatternE, MessagePatternDHEE}, + }, +} + +var HandshakeKN = HandshakePattern{ + Name: "KN", + InitiatorPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE}, + {MessagePatternE, MessagePatternDHEE, MessagePatternDHSE}, + }, +} + +var HandshakeNK = HandshakePattern{ + Name: "NK", + ResponderPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHES}, + {MessagePatternE, MessagePatternDHEE}, + }, +} + +var HandshakeKK = HandshakePattern{ + Name: "KK", + InitiatorPreMessages: []MessagePattern{MessagePatternS}, + ResponderPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHES, MessagePatternDHSS}, + {MessagePatternE, MessagePatternDHEE, MessagePatternDHSE}, + }, +} + +var HandshakeNX = HandshakePattern{ + Name: "NX", + Messages: [][]MessagePattern{ + {MessagePatternE}, + {MessagePatternE, MessagePatternDHEE, MessagePatternS, MessagePatternDHES}, + }, +} + +var HandshakeKX = HandshakePattern{ + Name: "KX", + InitiatorPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE}, + {MessagePatternE, MessagePatternDHEE, MessagePatternDHSE, MessagePatternS, MessagePatternDHES}, + }, +} + +var HandshakeXN = HandshakePattern{ + Name: "XN", + Messages: [][]MessagePattern{ + {MessagePatternE}, + {MessagePatternE, MessagePatternDHEE}, + {MessagePatternS, MessagePatternDHSE}, + }, +} + +var HandshakeIN = HandshakePattern{ + Name: "IN", + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternS}, + {MessagePatternE, MessagePatternDHEE, MessagePatternDHSE}, + }, +} + +var HandshakeXK = HandshakePattern{ + Name: "XK", + ResponderPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHES}, + {MessagePatternE, MessagePatternDHEE}, + {MessagePatternS, MessagePatternDHSE}, + }, +} + +var HandshakeIK = HandshakePattern{ + Name: "IK", + ResponderPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHES, MessagePatternS, MessagePatternDHSS}, + {MessagePatternE, MessagePatternDHEE, MessagePatternDHSE}, + }, +} + +var HandshakeXX = HandshakePattern{ + Name: "XX", + Messages: [][]MessagePattern{ + {MessagePatternE}, + {MessagePatternE, MessagePatternDHEE, MessagePatternS, MessagePatternDHES}, + {MessagePatternS, MessagePatternDHSE}, + }, +} + +var HandshakeXXfallback = HandshakePattern{ + Name: "XXfallback", + ResponderPreMessages: []MessagePattern{MessagePatternE}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHEE, MessagePatternS, MessagePatternDHSE}, + {MessagePatternS, MessagePatternDHES}, + }, +} + +var HandshakeIX = HandshakePattern{ + Name: "IX", + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternS}, + {MessagePatternE, MessagePatternDHEE, MessagePatternDHSE, MessagePatternS, MessagePatternDHES}, + }, +} + +var HandshakeN = HandshakePattern{ + Name: "N", + ResponderPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHES}, + }, +} + +var HandshakeK = HandshakePattern{ + Name: "K", + InitiatorPreMessages: []MessagePattern{MessagePatternS}, + ResponderPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHES, MessagePatternDHSS}, + }, +} + +var HandshakeX = HandshakePattern{ + Name: "X", + ResponderPreMessages: []MessagePattern{MessagePatternS}, + Messages: [][]MessagePattern{ + {MessagePatternE, MessagePatternDHES, MessagePatternS, MessagePatternDHSS}, + }, +} diff --git a/vendor/github.com/waku-org/noise/state.go b/vendor/github.com/waku-org/noise/state.go new file mode 100644 index 000000000..feefde8dd --- /dev/null +++ b/vendor/github.com/waku-org/noise/state.go @@ -0,0 +1,620 @@ +// Package noise implements the Noise Protocol Framework. +// +// Noise is a low-level framework for building crypto protocols. Noise protocols +// support mutual and optional authentication, identity hiding, forward secrecy, +// zero round-trip encryption, and other advanced features. For more details, +// visit https://noiseprotocol.org. +package noise + +import ( + "crypto/rand" + "errors" + "fmt" + "io" + "math" +) + +// A CipherState provides symmetric encryption and decryption after a successful +// handshake. +type CipherState struct { + cs CipherSuite + c Cipher + k [32]byte + n uint64 + + invalid bool +} + +// MaxNonce is the maximum value of n that is allowed. ErrMaxNonce is returned +// by Encrypt and Decrypt after this has been reached. 2^64-1 is reserved for rekeys. +const MaxNonce = uint64(math.MaxUint64) - 1 + +var ErrMaxNonce = errors.New("noise: cipherstate has reached maximum n, a new handshake must be performed") +var ErrCipherSuiteCopied = errors.New("noise: CipherSuite has been copied, state is invalid") + +// Encrypt encrypts the plaintext and then appends the ciphertext and an +// authentication tag across the ciphertext and optional authenticated data to +// out. This method automatically increments the nonce after every call, so +// messages must be decrypted in the same order. ErrMaxNonce is returned after +// the maximum nonce of 2^64-2 is reached. +func (s *CipherState) Encrypt(out, ad, plaintext []byte) ([]byte, error) { + if s.invalid { + return nil, ErrCipherSuiteCopied + } + if s.n > MaxNonce { + return nil, ErrMaxNonce + } + out = s.c.Encrypt(out, s.n, ad, plaintext) + s.n++ + return out, nil +} + +// Decrypt checks the authenticity of the ciphertext and authenticated data and +// then decrypts and appends the plaintext to out. This method automatically +// increments the nonce after every call, messages must be provided in the same +// order that they were encrypted with no missing messages. ErrMaxNonce is +// returned after the maximum nonce of 2^64-2 is reached. +func (s *CipherState) Decrypt(out, ad, ciphertext []byte) ([]byte, error) { + if s.invalid { + return nil, ErrCipherSuiteCopied + } + if s.n > MaxNonce { + return nil, ErrMaxNonce + } + out, err := s.c.Decrypt(out, s.n, ad, ciphertext) + if err != nil { + return nil, err + } + s.n++ + return out, nil +} + +// Cipher returns the low-level symmetric encryption primitive. It should only +// be used if nonces need to be managed manually, for example with a network +// protocol that can deliver out-of-order messages. This is dangerous, users +// must ensure that they are incrementing a nonce after every encrypt operation. +// After calling this method, it is an error to call Encrypt/Decrypt on the +// CipherState. +func (s *CipherState) Cipher() Cipher { + s.invalid = true + return s.c +} + +// Nonce returns the current value of n. This can be used to determine if a +// new handshake should be performed due to approaching MaxNonce. +func (s *CipherState) Nonce() uint64 { + return s.n +} + +// SetNonce sets the current value of n. +func (s *CipherState) SetNonce(n uint64) { + s.n = n +} + +func (s *CipherState) Rekey() { + var zeros [32]byte + var out []byte + out = s.c.Encrypt(out, math.MaxUint64, []byte{}, zeros[:]) + copy(s.k[:], out[:32]) + s.c = s.cs.Cipher(s.k) +} + +type symmetricState struct { + CipherState + hasK bool + ck []byte + h []byte + + prevCK []byte + prevH []byte +} + +func (s *symmetricState) InitializeSymmetric(handshakeName []byte) { + h := s.cs.Hash() + if len(handshakeName) <= h.Size() { + s.h = make([]byte, h.Size()) + copy(s.h, handshakeName) + } else { + h.Write(handshakeName) + s.h = h.Sum(nil) + } + s.ck = make([]byte, len(s.h)) + copy(s.ck, s.h) +} + +func (s *symmetricState) MixKey(dhOutput []byte) { + s.n = 0 + s.hasK = true + var hk []byte + s.ck, hk, _ = hkdf(s.cs.Hash, 2, s.ck[:0], s.k[:0], nil, s.ck, dhOutput) + copy(s.k[:], hk) + s.c = s.cs.Cipher(s.k) +} + +func (s *symmetricState) MixHash(data []byte) { + h := s.cs.Hash() + h.Write(s.h) + h.Write(data) + s.h = h.Sum(s.h[:0]) +} + +func (s *symmetricState) MixKeyAndHash(data []byte) { + var hk []byte + var temp []byte + s.ck, temp, hk = hkdf(s.cs.Hash, 3, s.ck[:0], temp, s.k[:0], s.ck, data) + s.MixHash(temp) + copy(s.k[:], hk) + s.c = s.cs.Cipher(s.k) + s.n = 0 + s.hasK = true +} + +func (s *symmetricState) EncryptAndHash(out, plaintext []byte) ([]byte, error) { + if !s.hasK { + s.MixHash(plaintext) + return append(out, plaintext...), nil + } + ciphertext, err := s.Encrypt(out, s.h, plaintext) + if err != nil { + return nil, err + } + s.MixHash(ciphertext[len(out):]) + return ciphertext, nil +} + +func (s *symmetricState) DecryptAndHash(out, data []byte) ([]byte, error) { + if !s.hasK { + s.MixHash(data) + return append(out, data...), nil + } + plaintext, err := s.Decrypt(out, s.h, data) + if err != nil { + return nil, err + } + s.MixHash(data) + return plaintext, nil +} + +func (s *symmetricState) Split() (*CipherState, *CipherState) { + s1, s2 := &CipherState{cs: s.cs}, &CipherState{cs: s.cs} + hk1, hk2, _ := hkdf(s.cs.Hash, 2, s1.k[:0], s2.k[:0], nil, s.ck, nil) + copy(s1.k[:], hk1) + copy(s2.k[:], hk2) + s1.c = s.cs.Cipher(s1.k) + s2.c = s.cs.Cipher(s2.k) + return s1, s2 +} + +func (s *symmetricState) Checkpoint() { + if len(s.ck) > cap(s.prevCK) { + s.prevCK = make([]byte, len(s.ck)) + } + s.prevCK = s.prevCK[:len(s.ck)] + copy(s.prevCK, s.ck) + + if len(s.h) > cap(s.prevH) { + s.prevH = make([]byte, len(s.h)) + } + s.prevH = s.prevH[:len(s.h)] + copy(s.prevH, s.h) +} + +func (s *symmetricState) Rollback() { + s.ck = s.ck[:len(s.prevCK)] + copy(s.ck, s.prevCK) + s.h = s.h[:len(s.prevH)] + copy(s.h, s.prevH) +} + +// A MessagePattern is a single message or operation used in a Noise handshake. +type MessagePattern int + +// A HandshakePattern is a list of messages and operations that are used to +// perform a specific Noise handshake. +type HandshakePattern struct { + Name string + InitiatorPreMessages []MessagePattern + ResponderPreMessages []MessagePattern + Messages [][]MessagePattern +} + +const ( + MessagePatternS MessagePattern = iota + MessagePatternE + MessagePatternDHEE + MessagePatternDHES + MessagePatternDHSE + MessagePatternDHSS + MessagePatternPSK +) + +// MaxMsgLen is the maximum number of bytes that can be sent in a single Noise +// message. +const MaxMsgLen = 65535 + +// A HandshakeState tracks the state of a Noise handshake. It may be discarded +// after the handshake is complete. +type HandshakeState struct { + ss symmetricState + s DHKey // local static keypair + e DHKey // local ephemeral keypair + rs []byte // remote party's static public key + re []byte // remote party's ephemeral public key + psk []byte // preshared key, maybe zero length + messagePatterns [][]MessagePattern + shouldWrite bool + initiator bool + msgIdx int + rng io.Reader +} + +// A Config provides the details necessary to process a Noise handshake. It is +// never modified by this package, and can be reused. +type Config struct { + // CipherSuite is the set of cryptographic primitives that will be used. + CipherSuite CipherSuite + + // Random is the source for cryptographically appropriate random bytes. If + // zero, it is automatically configured. + Random io.Reader + + // Pattern is the pattern for the handshake. + Pattern HandshakePattern + + // Initiator must be true if the first message in the handshake will be sent + // by this peer. + Initiator bool + + // Prologue is an optional message that has already be communicated and must + // be identical on both sides for the handshake to succeed. + Prologue []byte + + // PresharedKey is the optional preshared key for the handshake. + PresharedKey []byte + + // PresharedKeyPlacement specifies the placement position of the PSK token + // when PresharedKey is specified + PresharedKeyPlacement int + + // StaticKeypair is this peer's static keypair, required if part of the + // handshake. + StaticKeypair DHKey + + // EphemeralKeypair is this peer's ephemeral keypair that was provided as + // a pre-message in the handshake. + EphemeralKeypair DHKey + + // PeerStatic is the static public key of the remote peer that was provided + // as a pre-message in the handshake. + PeerStatic []byte + + // PeerEphemeral is the ephemeral public key of the remote peer that was + // provided as a pre-message in the handshake. + PeerEphemeral []byte +} + +// NewHandshakeState starts a new handshake using the provided configuration. +func NewHandshakeState(c Config) (*HandshakeState, error) { + hs := &HandshakeState{ + s: c.StaticKeypair, + e: c.EphemeralKeypair, + rs: c.PeerStatic, + psk: c.PresharedKey, + messagePatterns: c.Pattern.Messages, + shouldWrite: c.Initiator, + initiator: c.Initiator, + rng: c.Random, + } + if hs.rng == nil { + hs.rng = rand.Reader + } + if len(c.PeerEphemeral) > 0 { + hs.re = make([]byte, len(c.PeerEphemeral)) + copy(hs.re, c.PeerEphemeral) + } + hs.ss.cs = c.CipherSuite + pskModifier := "" + if len(hs.psk) > 0 { + if len(hs.psk) != 32 { + return nil, errors.New("noise: specification mandates 256-bit preshared keys") + } + pskModifier = fmt.Sprintf("psk%d", c.PresharedKeyPlacement) + hs.messagePatterns = append([][]MessagePattern(nil), hs.messagePatterns...) + if c.PresharedKeyPlacement == 0 { + hs.messagePatterns[0] = append([]MessagePattern{MessagePatternPSK}, hs.messagePatterns[0]...) + } else { + hs.messagePatterns[c.PresharedKeyPlacement-1] = append(hs.messagePatterns[c.PresharedKeyPlacement-1], MessagePatternPSK) + } + } + hs.ss.InitializeSymmetric([]byte("Noise_" + c.Pattern.Name + pskModifier + "_" + string(hs.ss.cs.Name()))) + hs.ss.MixHash(c.Prologue) + for _, m := range c.Pattern.InitiatorPreMessages { + switch { + case c.Initiator && m == MessagePatternS: + hs.ss.MixHash(hs.s.Public) + case c.Initiator && m == MessagePatternE: + hs.ss.MixHash(hs.e.Public) + case !c.Initiator && m == MessagePatternS: + hs.ss.MixHash(hs.rs) + case !c.Initiator && m == MessagePatternE: + hs.ss.MixHash(hs.re) + } + } + for _, m := range c.Pattern.ResponderPreMessages { + switch { + case !c.Initiator && m == MessagePatternS: + hs.ss.MixHash(hs.s.Public) + case !c.Initiator && m == MessagePatternE: + hs.ss.MixHash(hs.e.Public) + case c.Initiator && m == MessagePatternS: + hs.ss.MixHash(hs.rs) + case c.Initiator && m == MessagePatternE: + hs.ss.MixHash(hs.re) + } + } + return hs, nil +} + +// WriteMessage appends a handshake message to out. The message will include the +// optional payload if provided. If the handshake is completed by the call, two +// CipherStates will be returned, one is used for encryption of messages to the +// remote peer, the other is used for decryption of messages from the remote +// peer. It is an error to call this method out of sync with the handshake +// pattern. +func (s *HandshakeState) WriteMessage(out, payload []byte) ([]byte, *CipherState, *CipherState, error) { + out, _, cs1, cs2, err := s.WriteMessageAndGetPK(out, [][]byte{}, payload) + return out, cs1, cs2, err +} + +// WriteMessageAndGetPK appends a handshake message to out. outPK can possibly contain the +// party public keys. The message will include the optional payload if provided. +// If the handshake is completed by the call, two CipherStates will be returned, +// one is used for encryption of messages to the remote peer, the other is used +// for decryption of messages from the remote peer. It is an error to call this +// method out of sync with the handshake pattern. +func (s *HandshakeState) WriteMessageAndGetPK(out []byte, outPK [][]byte, payload []byte) ([]byte, [][]byte, *CipherState, *CipherState, error) { + if !s.shouldWrite { + return nil, nil, nil, nil, errors.New("noise: unexpected call to WriteMessage should be ReadMessage") + } + if s.msgIdx > len(s.messagePatterns)-1 { + return nil, nil, nil, nil, errors.New("noise: no handshake messages left") + } + if len(payload) > MaxMsgLen { + return nil, nil, nil, nil, errors.New("noise: message is too long") + } + + var err error + for _, msg := range s.messagePatterns[s.msgIdx] { + switch msg { + case MessagePatternE: + e, err := s.ss.cs.GenerateKeypair(s.rng) + if err != nil { + return nil, nil, nil, nil, err + } + s.e = e + out = append(out, s.e.Public...) + outPK = append(outPK, s.e.Public) + + s.ss.MixHash(s.e.Public) + if len(s.psk) > 0 { + s.ss.MixKey(s.e.Public) + } + case MessagePatternS: + if len(s.s.Public) == 0 { + return nil, nil, nil, nil, errors.New("noise: invalid state, s.Public is nil") + } + out, err = s.ss.EncryptAndHash(out, s.s.Public) + outPK = append(outPK, out) + if err != nil { + return nil, nil, nil, nil, err + } + + case MessagePatternDHEE: + dh, err := s.ss.cs.DH(s.e.Private, s.re) + if err != nil { + return nil, nil, nil, nil, err + } + s.ss.MixKey(dh) + case MessagePatternDHES: + if s.initiator { + dh, err := s.ss.cs.DH(s.e.Private, s.rs) + if err != nil { + return nil, nil, nil, nil, err + } + s.ss.MixKey(dh) + } else { + dh, err := s.ss.cs.DH(s.s.Private, s.re) + if err != nil { + return nil, nil, nil, nil, err + } + s.ss.MixKey(dh) + } + case MessagePatternDHSE: + if s.initiator { + dh, err := s.ss.cs.DH(s.s.Private, s.re) + if err != nil { + return nil, nil, nil, nil, err + } + s.ss.MixKey(dh) + } else { + dh, err := s.ss.cs.DH(s.e.Private, s.rs) + if err != nil { + return nil, nil, nil, nil, err + } + s.ss.MixKey(dh) + } + case MessagePatternDHSS: + dh, err := s.ss.cs.DH(s.s.Private, s.rs) + if err != nil { + return nil, nil, nil, nil, err + } + s.ss.MixKey(dh) + case MessagePatternPSK: + s.ss.MixKeyAndHash(s.psk) + } + } + s.shouldWrite = false + s.msgIdx++ + out, err = s.ss.EncryptAndHash(out, payload) + if err != nil { + return nil, nil, nil, nil, err + } + + if s.msgIdx >= len(s.messagePatterns) { + cs1, cs2 := s.ss.Split() + return out, outPK, cs1, cs2, nil + } + + return out, outPK, nil, nil, nil +} + +// ErrShortMessage is returned by ReadMessage if a message is not as long as it should be. +var ErrShortMessage = errors.New("noise: message is too short") + +// ReadMessage processes a received handshake message and appends the payload, +// if any to out. If the handshake is completed by the call, two CipherStates +// will be returned, one is used for encryption of messages to the remote peer, +// the other is used for decryption of messages from the remote peer. It is an +// error to call this method out of sync with the handshake pattern. +func (s *HandshakeState) ReadMessage(out, message []byte) ([]byte, *CipherState, *CipherState, error) { + if s.shouldWrite { + return nil, nil, nil, errors.New("noise: unexpected call to ReadMessage should be WriteMessage") + } + if s.msgIdx > len(s.messagePatterns)-1 { + return nil, nil, nil, errors.New("noise: no handshake messages left") + } + + rsSet := false + s.ss.Checkpoint() + + var err error + for _, msg := range s.messagePatterns[s.msgIdx] { + switch msg { + case MessagePatternE, MessagePatternS: + expected := s.ss.cs.DHLen() + if msg == MessagePatternS && s.ss.hasK { + expected += 16 + } + if len(message) < expected { + return nil, nil, nil, ErrShortMessage + } + switch msg { + case MessagePatternE: + if cap(s.re) < s.ss.cs.DHLen() { + s.re = make([]byte, s.ss.cs.DHLen()) + } + s.re = s.re[:s.ss.cs.DHLen()] + copy(s.re, message) + s.ss.MixHash(s.re) + if len(s.psk) > 0 { + s.ss.MixKey(s.re) + } + case MessagePatternS: + if len(s.rs) > 0 { + return nil, nil, nil, errors.New("noise: invalid state, rs is not nil") + } + s.rs, err = s.ss.DecryptAndHash(s.rs[:0], message[:expected]) + rsSet = true + } + if err != nil { + s.ss.Rollback() + if rsSet { + s.rs = nil + } + return nil, nil, nil, err + } + message = message[expected:] + case MessagePatternDHEE: + dh, err := s.ss.cs.DH(s.e.Private, s.re) + if err != nil { + return nil, nil, nil, err + } + s.ss.MixKey(dh) + case MessagePatternDHES: + if s.initiator { + dh, err := s.ss.cs.DH(s.e.Private, s.rs) + if err != nil { + return nil, nil, nil, err + } + s.ss.MixKey(dh) + } else { + dh, err := s.ss.cs.DH(s.s.Private, s.re) + if err != nil { + return nil, nil, nil, err + } + s.ss.MixKey(dh) + } + case MessagePatternDHSE: + if s.initiator { + dh, err := s.ss.cs.DH(s.s.Private, s.re) + if err != nil { + return nil, nil, nil, err + } + s.ss.MixKey(dh) + } else { + dh, err := s.ss.cs.DH(s.e.Private, s.rs) + if err != nil { + return nil, nil, nil, err + } + s.ss.MixKey(dh) + } + case MessagePatternDHSS: + dh, err := s.ss.cs.DH(s.s.Private, s.rs) + if err != nil { + return nil, nil, nil, err + } + s.ss.MixKey(dh) + case MessagePatternPSK: + s.ss.MixKeyAndHash(s.psk) + } + } + out, err = s.ss.DecryptAndHash(out, message) + if err != nil { + s.ss.Rollback() + if rsSet { + s.rs = nil + } + return nil, nil, nil, err + } + s.shouldWrite = true + s.msgIdx++ + + if s.msgIdx >= len(s.messagePatterns) { + cs1, cs2 := s.ss.Split() + return out, cs1, cs2, nil + } + + return out, nil, nil, nil +} + +// ChannelBinding provides a value that uniquely identifies the session and can +// be used as a channel binding. It is an error to call this method before the +// handshake is complete. +func (s *HandshakeState) ChannelBinding() []byte { + return s.ss.h +} + +// PeerStatic returns the static key provided by the remote peer during +// a handshake. It is an error to call this method if a handshake message +// containing a static key has not been read. +func (s *HandshakeState) PeerStatic() []byte { + return s.rs +} + +// MessageIndex returns the current handshake message id +func (s *HandshakeState) MessageIndex() int { + return s.msgIdx +} + +// PeerEphemeral returns the ephemeral key provided by the remote peer during +// a handshake. It is an error to call this method if a handshake message +// containing a static key has not been read. +func (s *HandshakeState) PeerEphemeral() []byte { + return s.re +} + +// LocalEphemeral returns the local ephemeral key pair generated during +// a handshake. +func (s *HandshakeState) LocalEphemeral() DHKey { + return s.e +} diff --git a/vendor/github.com/waku-org/noise/vectors.txt b/vendor/github.com/waku-org/noise/vectors.txt new file mode 100644 index 000000000..344ab7558 --- /dev/null +++ b/vendor/github.com/waku-org/noise/vectors.txt @@ -0,0 +1,28640 @@ +handshake=Noise_NN_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667cc0d7b4540fd183ba30ecbd3f464f16 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0193b62b90fb3497108ec8adcc340a49ebb0a07f1654d71f7e38361f57ba5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b2afdcb051e896fa5b6a23def5ee6bdd6032f1b39b2d22ef7da01857648389 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544833316e6c21d899aec6c5f0c6e85e13 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d3ec4419885d86e6d7310fb1d2263afd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a7b199c69a64cc2ea3c556cf17489fd2ae452d3f3c2a0871cebd327fc31c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e58d43e0c69d8c15df523586b2c58ca40cb0472b5b3775f1cca807fee28a71 + +handshake=Noise_NNpsk1_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da8ea488f6163eeccb6d3836ec6ccefd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666f14491c4b69e43af265c51f3c3c09a7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84a7c955143ce45834b0acdef085054ab1a321668d7045dafc67b3e189f66d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44cb770629debcb89480285522a1fd693b666884f7758f6f864c09c538c119 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625407418737b0236214775b43573cb13a23 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6a7d8b64f54b20c5f93066303fb3170 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84c7ad0cff2af00d6c12896f0230233a99e1abeaef043747035d9a38c06f9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4bdd4800b3abd620ce9f4c519428acf7912af8b6507aa3befecce2444d2614 + +handshake=Noise_NN_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663d8d136c2fcf7ecd3c3d631843bc33819e3a01f9b58040751011 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0193b62b90fb3497108ec8adcc340a49ebb0a07f1654d71f7e38361f57ba5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b2afdcb051e896fa5b6a23def5ee6bdd6032f1b39b2d22ef7da01857648389 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d2f8054fcaf80f34700607e4422560b0626b1bc69e65290f6437 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e21a3177614fce09f014bde7e996fb8c8300777068e6fd2aa7c4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a7b199c69a64cc2ea3c556cf17489fd2ae452d3f3c2a0871cebd327fc31c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e58d43e0c69d8c15df523586b2c58ca40cb0472b5b3775f1cca807fee28a71 + +handshake=Noise_NNpsk1_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254422cb9f10bb05f92da10138bc8c286b5aa2f756e90b8edf48acb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d48f5698c6af1a7d6f1c5755e27285251fe4aa9074a3ba30c3ca +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84a7c955143ce45834b0acdef085054ab1a321668d7045dafc67b3e189f66d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44cb770629debcb89480285522a1fd693b666884f7758f6f864c09c538c119 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547bddd25c5d196f5110f02adbbd877b69e8a86f44e2aaa0ee24aa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ad1970fd7307e7594135cfec5a24fac90fc08bc1b0f393ec250c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84c7ad0cff2af00d6c12896f0230233a99e1abeaef043747035d9a38c06f9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4bdd4800b3abd620ce9f4c519428acf7912af8b6507aa3befecce2444d2614 + +handshake=Noise_NN_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662529efae98611941ab23ad370919a7f5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0193b62b90fb3497108ec8adcc340a49ebb0a07f1654d71f7e38361f57ba5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b2afdcb051e896fa5b6a23def5ee6bdd6032f1b39b2d22ef7da01857648389 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625486959ba2f588031f633a6c0e54a14ae5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c8783e80be055a8f51e32418393af7cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a7b199c69a64cc2ea3c556cf17489fd2ae452d3f3c2a0871cebd327fc31c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e58d43e0c69d8c15df523586b2c58ca40cb0472b5b3775f1cca807fee28a71 + +handshake=Noise_NNpsk1_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a0328c29b33470d04740e97e9514cbcd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668badb8f25007a52eef9d16009be2c712 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84a7c955143ce45834b0acdef085054ab1a321668d7045dafc67b3e189f66d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44cb770629debcb89480285522a1fd693b666884f7758f6f864c09c538c119 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540dae00c4de099415fc994fe385a4c2e5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666a126d2d8d2dff1221cb69310cca148f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84c7ad0cff2af00d6c12896f0230233a99e1abeaef043747035d9a38c06f9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4bdd4800b3abd620ce9f4c519428acf7912af8b6507aa3befecce2444d2614 + +handshake=Noise_NN_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663d8d136c2fcf7ecd3c3d4c93591205092db481f2a901eb96f06c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0193b62b90fb3497108ec8adcc340a49ebb0a07f1654d71f7e38361f57ba5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b2afdcb051e896fa5b6a23def5ee6bdd6032f1b39b2d22ef7da01857648389 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d2f8054fcaf80f347006e0fc25590a31fd33c4626fe59283ea40 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e21a3177614fce09f014af55e853ed6b88b0e4628e071b23e905 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a7b199c69a64cc2ea3c556cf17489fd2ae452d3f3c2a0871cebd327fc31c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e58d43e0c69d8c15df523586b2c58ca40cb0472b5b3775f1cca807fee28a71 + +handshake=Noise_NNpsk1_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254422cb9f10bb05f92da1086ba7a3f7fdeede2360802fce2bab641 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d48f5698c6af1a7d6f1cce81b2d248ccdd0f13d7c85b6b61d30a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84a7c955143ce45834b0acdef085054ab1a321668d7045dafc67b3e189f66d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44cb770629debcb89480285522a1fd693b666884f7758f6f864c09c538c119 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547bddd25c5d196f5110f0e47e04cd720aa46674d274f35cc9219a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ad1970fd7307e7594135c3fbe2866e29c265002153e2342cf6a0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84c7ad0cff2af00d6c12896f0230233a99e1abeaef043747035d9a38c06f9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4bdd4800b3abd620ce9f4c519428acf7912af8b6507aa3befecce2444d2614 + +handshake=Noise_KN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466827d5016baa63241017945dea7aeb9be +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d8eb7e92e6ffa800b669953e5a1b99fe268df1161d7293a1c1836f7dd2d55b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=009f1432e8414277b5ddf687ae0daf50f76e24c5ed30b0d1e4af53544c70ad + +handshake=Noise_KNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254169cf5ede5a37b6318901ccb41cfc0e6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846625bfff2e7a6576de4563a805d0cc79ad +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e3cfa09d18879571feb6c1b8656bd2c1768f636b70f269473f795eb26efe04 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a2f6c5b843b9306af62414b072ef527322ee7c77fcbdcf3774c85a0f62ee29 + +handshake=Noise_KNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542b4b5f5a0d01587d693384d5fa9b816d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e2b2821c8dd067005f3942c533057774 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2eba684f829bd3225ffd18163e51830268c3107086c6a5c6c8861324a84118 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00b6cddef82e1313dd1f4a5e2e63aff31c9a39160698ee7b81b00e72c20082 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543212e39efee8148627b3aeb4e1a997d2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c1a5d67a8aa44d84bc1d1310365f02a5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17bb34185e6ca8171a04f52a87e4b372b2a0c871444050890b9e6d64775a30 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d607e4acbb0b137bb7956fe26d648088a9865b25376513351b0ed019e5c098 + +handshake=Noise_KN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fc79472c53cf5dde06848020738862f3268987d895428bdd974b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d8eb7e92e6ffa800b669953e5a1b99fe268df1161d7293a1c1836f7dd2d55b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=009f1432e8414277b5ddf687ae0daf50f76e24c5ed30b0d1e4af53544c70ad + +handshake=Noise_KNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d65483c2c037a3715bfd2e8bceb4633a3758a492725e6cb94082 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466653bddb937e507c9febf96843ce9aedca6013fb23cd2c54fd3cf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e3cfa09d18879571feb6c1b8656bd2c1768f636b70f269473f795eb26efe04 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a2f6c5b843b9306af62414b072ef527322ee7c77fcbdcf3774c85a0f62ee29 + +handshake=Noise_KNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7207c975f3cc6901b9d650f4f768838f45cb1899c96808a8b7c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664685702a41068df357c8ba5150d0e340cde8073a959298579680 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2eba684f829bd3225ffd18163e51830268c3107086c6a5c6c8861324a84118 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00b6cddef82e1313dd1f4a5e2e63aff31c9a39160698ee7b81b00e72c20082 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d109459bac52bf108d0aeee64b8e84f04273f7423b0ae575df25 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665d5f1ae785b46ce05fded66b0c412e1d35aea492cdafed0410eb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17bb34185e6ca8171a04f52a87e4b372b2a0c871444050890b9e6d64775a30 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d607e4acbb0b137bb7956fe26d648088a9865b25376513351b0ed019e5c098 + +handshake=Noise_KN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f4f7f9d6b31a498dbd6a5e3507e7dc97 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d8eb7e92e6ffa800b669953e5a1b99fe268df1161d7293a1c1836f7dd2d55b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=009f1432e8414277b5ddf687ae0daf50f76e24c5ed30b0d1e4af53544c70ad + +handshake=Noise_KNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625439382eef6b7cd99fa9cd2ff31146a7e7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fbb960fdc82cf9a7808990194e3c706b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e3cfa09d18879571feb6c1b8656bd2c1768f636b70f269473f795eb26efe04 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a2f6c5b843b9306af62414b072ef527322ee7c77fcbdcf3774c85a0f62ee29 + +handshake=Noise_KNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625404c68e7f550e27c9cc7b2c2edb4de4a7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669ac747a0a01f904299ac44304fb4c552 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2eba684f829bd3225ffd18163e51830268c3107086c6a5c6c8861324a84118 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00b6cddef82e1313dd1f4a5e2e63aff31c9a39160698ee7b81b00e72c20082 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254546bebfef90b0b870b4e9596efcc7447 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664c8f298e9f683830ecef7654eac5efae +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17bb34185e6ca8171a04f52a87e4b372b2a0c871444050890b9e6d64775a30 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d607e4acbb0b137bb7956fe26d648088a9865b25376513351b0ed019e5c098 + +handshake=Noise_KN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fc79472c53cf5dde06842c7bbaddce7a78d729b83d1579fee94c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d8eb7e92e6ffa800b669953e5a1b99fe268df1161d7293a1c1836f7dd2d55b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=009f1432e8414277b5ddf687ae0daf50f76e24c5ed30b0d1e4af53544c70ad + +handshake=Noise_KNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d65483c2c037a3715bfd42574061e8d814661165acbf6eedb5c6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466653bddb937e507c9febfa60df671aeed8ee66f0e986dfeaa0865 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e3cfa09d18879571feb6c1b8656bd2c1768f636b70f269473f795eb26efe04 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a2f6c5b843b9306af62414b072ef527322ee7c77fcbdcf3774c85a0f62ee29 + +handshake=Noise_KNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7207c975f3cc6901b9da3e1a6491825efcc2dd70646ab8cb898 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664685702a41068df357c8a9d8abd0235d963ad2dcf235a6f353f5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2eba684f829bd3225ffd18163e51830268c3107086c6a5c6c8861324a84118 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00b6cddef82e1313dd1f4a5e2e63aff31c9a39160698ee7b81b00e72c20082 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d109459bac52bf108d0a86488e517a3e603907489b5fc4a7311b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665d5f1ae785b46ce05fdea603c6ef38009c36fe4846c921c6326b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17bb34185e6ca8171a04f52a87e4b372b2a0c871444050890b9e6d64775a30 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d607e4acbb0b137bb7956fe26d648088a9865b25376513351b0ed019e5c098 + +handshake=Noise_NK_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625418e3e3b9a33b9d5f680ee08fbf20d03f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a2c11719e1aac7b6b2efc4871618f8bf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95922788fcef822a17b42f450fa14d05d8e6a4377ca0aea3b4804f03db74a2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0976cd4a786c253b37489b6bc3867b2df0dddf9f939b218da54092c6d3eca4 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f965755a00eab9d92efbcdfbcc9e3b63 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c07c73cd24ea666246bc2ce129914dd3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=093acd47149fadf3574dd440428181edf9c61cc4a1b5ef815e8b779f1bbf40 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2b8e170039917a61d4fe8acbd2147d50afafc32070458b51b666225614f364 + +handshake=Noise_NKpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625461500ecd7d2df0e7b6517f899a562cdd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660c7c4d7f118e1fe8345ffceee554dc1b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=51fd5d7489dae3d6a99766db0afe89c1d19ed91a80b1bb64f94e747360fd2c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=be24f94a04505c8ab51768a80b388f2758ddab3b2fa3eebfeaceeff0130d78 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625498189a3c42ac5c0817de56867c43b2e5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668f7ced987ac0a5d56835254fc6374a82 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d848f074d3d766c1a7770c51ceba699a16ad262790fc279e7dd2fcccfd4dca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=51f74c4a80c3768dd6476fbb9c599efe5491567af3d18c8415d9d017821004 + +handshake=Noise_NK_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546cfcd5c91dd95543a236cd276e885b5c7a1c3890ca630f06543e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b3f3dd3e34414275ad733b2a5593f9b31485eecd7c12413912a9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95922788fcef822a17b42f450fa14d05d8e6a4377ca0aea3b4804f03db74a2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0976cd4a786c253b37489b6bc3867b2df0dddf9f939b218da54092c6d3eca4 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625485932c8c7615c8263798b4f9d548cb656be5a4eb30cd9a0485c9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cce9cb21a513f9de326cba676712ee32441eb2146407fba7b57e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=093acd47149fadf3574dd440428181edf9c61cc4a1b5ef815e8b779f1bbf40 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2b8e170039917a61d4fe8acbd2147d50afafc32070458b51b666225614f364 + +handshake=Noise_NKpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543f74b70b971271ffb3efb21dfeb1ea4ec9039c91a237de4027a5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669920e429a6643b44e75fa65798b735a87d8c1edbd6013455a404 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=51fd5d7489dae3d6a99766db0afe89c1d19ed91a80b1bb64f94e747360fd2c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=be24f94a04505c8ab51768a80b388f2758ddab3b2fa3eebfeaceeff0130d78 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254537ac869369393768b2148856b6ab4aa465dbf8b6ff26007937a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846695f32217406ccaa2da8f4a639bd9b5656007964aeaf74c7c377d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d848f074d3d766c1a7770c51ceba699a16ad262790fc279e7dd2fcccfd4dca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=51f74c4a80c3768dd6476fbb9c599efe5491567af3d18c8415d9d017821004 + +handshake=Noise_NK_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f256569b87bb96d615490cfa4ca93b30 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664918946d495163ba4efd4dfea52402eb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95922788fcef822a17b42f450fa14d05d8e6a4377ca0aea3b4804f03db74a2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0976cd4a786c253b37489b6bc3867b2df0dddf9f939b218da54092c6d3eca4 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6679a09e77ede865a31906c6f3c9537 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466833a2e7d79a0dbfc47f93bd7c4442646 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=093acd47149fadf3574dd440428181edf9c61cc4a1b5ef815e8b779f1bbf40 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2b8e170039917a61d4fe8acbd2147d50afafc32070458b51b666225614f364 + +handshake=Noise_NKpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625402b4cfd1e0bc207c3f2a5459c6993328 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466065a03c65cc319c55bde1813028060ce +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=51fd5d7489dae3d6a99766db0afe89c1d19ed91a80b1bb64f94e747360fd2c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=be24f94a04505c8ab51768a80b388f2758ddab3b2fa3eebfeaceeff0130d78 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546de0aeb2f4a18513ac55eea1fbbe4de8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846626379fd9720128b0dbbaa6734fd5b9e0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d848f074d3d766c1a7770c51ceba699a16ad262790fc279e7dd2fcccfd4dca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=51f74c4a80c3768dd6476fbb9c599efe5491567af3d18c8415d9d017821004 + +handshake=Noise_NK_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546cfcd5c91dd95543a2363b9bd07c092d8fff14687e5f48b43afc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b3f3dd3e34414275ad73c9d7e1d03e86e1580404241350ed9ab1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95922788fcef822a17b42f450fa14d05d8e6a4377ca0aea3b4804f03db74a2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0976cd4a786c253b37489b6bc3867b2df0dddf9f939b218da54092c6d3eca4 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625485932c8c7615c82637987b6d1508724221d9ac49e27a147f5b20 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cce9cb21a513f9de326ccb24b4012111db3db7d41383ad139bf4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=093acd47149fadf3574dd440428181edf9c61cc4a1b5ef815e8b779f1bbf40 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2b8e170039917a61d4fe8acbd2147d50afafc32070458b51b666225614f364 + +handshake=Noise_NKpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543f74b70b971271ffb3ef260b21a3f29655bee689e501c2a16b89 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669920e429a6643b44e75f92aa79146466904a0217560ee27b49df +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=51fd5d7489dae3d6a99766db0afe89c1d19ed91a80b1bb64f94e747360fd2c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=be24f94a04505c8ab51768a80b388f2758ddab3b2fa3eebfeaceeff0130d78 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254537ac869369393768b21c12506b70b078d6cb28378d02e8d93af +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846695f32217406ccaa2da8ffcd2908a04cb425c65daad407f91f131 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d848f074d3d766c1a7770c51ceba699a16ad262790fc279e7dd2fcccfd4dca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=51f74c4a80c3768dd6476fbb9c599efe5491567af3d18c8415d9d017821004 + +handshake=Noise_KK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543f53f25dc2eca97efae6a4a4b847de06 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f506ffcf6b2781821b24b70b8fad884 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0e79035855cdea04bc833d5ff63291042c6e12b0ac55ef2c4096deed1cbac2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c6dbcc2ac8f85338732b71a58f4c3be89bdfa7b2da8a8506ec4f1d2d9299a0 + +handshake=Noise_KKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f8ec97c143e2e9193574ea4989ebc3a2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668021ddcdb7eb8e89d8034de9248af340 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13f09ec7877b005731a876958cec004a7f9c2734e971828082db441ce001c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cf3a9cb9da7eb9bea19447b1f9bea60ac70124dfef886e9b82cd52f748c682 + +handshake=Noise_KKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542a366ea33985fc1669836b873058f89a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664aad05b9467f884f79f963ec5febb35f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96252868cb85131fc634b43f37c135da2b02902158369ec7a8e6b45b246732 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52822ad96c98c7ebcf68cafe91b6f18929aad75af5424a973cdb0f004b3832 + +handshake=Noise_KKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b7cf6c9cefd4f1fb33dddd9f27acdb20 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661fe30c2f7bbae74d87402b1cd73c4862 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d219ab65f4416d18e67f501afa99f43009c0a1c2c78427b1dcbdd6cf020928 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1c6b3e31392287e06fcc5a885ea8690e39a2d3d54e23f5aeca14fca3c2f053 + +handshake=Noise_KK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f076403f2e0cdd201c5aae9d1539c9ad90262eefea9c90a5397b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f12abbcda56565bf3fa3254fe35ad97f3e9d5e25aa296741ec3e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0e79035855cdea04bc833d5ff63291042c6e12b0ac55ef2c4096deed1cbac2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c6dbcc2ac8f85338732b71a58f4c3be89bdfa7b2da8a8506ec4f1d2d9299a0 + +handshake=Noise_KKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625413c6b4c495bbc7b95432907247ab38b5bb507bcf4f32abbd490e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466169cfd28ccd38213e17be5b967a6ff6de85f6949f26824243711 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13f09ec7877b005731a876958cec004a7f9c2734e971828082db441ce001c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cf3a9cb9da7eb9bea19447b1f9bea60ac70124dfef886e9b82cd52f748c682 + +handshake=Noise_KKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f45eb20acd443feff46beebe27c56ffdd58063a70d706f8640c6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d510ee9dd1b542ca5a0d0c5756779245766d964eef8f34867872 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96252868cb85131fc634b43f37c135da2b02902158369ec7a8e6b45b246732 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52822ad96c98c7ebcf68cafe91b6f18929aad75af5424a973cdb0f004b3832 + +handshake=Noise_KKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540590c32754712b9ce391e4773cd5b7c761ef65b6cb530ab10d8f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1bd851e93bfded9a6c7d56b6672e23bdc4a53bdc9e10961b1f0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d219ab65f4416d18e67f501afa99f43009c0a1c2c78427b1dcbdd6cf020928 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1c6b3e31392287e06fcc5a885ea8690e39a2d3d54e23f5aeca14fca3c2f053 + +handshake=Noise_KK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d05f754c90d580f21b243391fe987af4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f8f3babbd403b9665488570810b364dd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0e79035855cdea04bc833d5ff63291042c6e12b0ac55ef2c4096deed1cbac2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c6dbcc2ac8f85338732b71a58f4c3be89bdfa7b2da8a8506ec4f1d2d9299a0 + +handshake=Noise_KKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625420f8e0f9c7579f754ce9b5e05f5cee81 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b05668d3dcd247a08e099cbeb58174df +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13f09ec7877b005731a876958cec004a7f9c2734e971828082db441ce001c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cf3a9cb9da7eb9bea19447b1f9bea60ac70124dfef886e9b82cd52f748c682 + +handshake=Noise_KKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546bfe451377763da7a318dbfc124530f9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662f550d35da0ef73348c5f2a8be605444 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96252868cb85131fc634b43f37c135da2b02902158369ec7a8e6b45b246732 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52822ad96c98c7ebcf68cafe91b6f18929aad75af5424a973cdb0f004b3832 + +handshake=Noise_KKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625456ad94f8b8869d6b972be9a552537a3c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dfd7a0cc157b4afc52ff249d573f1358 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d219ab65f4416d18e67f501afa99f43009c0a1c2c78427b1dcbdd6cf020928 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1c6b3e31392287e06fcc5a885ea8690e39a2d3d54e23f5aeca14fca3c2f053 + +handshake=Noise_KK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f076403f2e0cdd201c5a743d4aab448e6e3b29d4aa05628a5cbd +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f12abbcda56565bf3fa37b196488daf515b7434096aa1638346b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0e79035855cdea04bc833d5ff63291042c6e12b0ac55ef2c4096deed1cbac2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c6dbcc2ac8f85338732b71a58f4c3be89bdfa7b2da8a8506ec4f1d2d9299a0 + +handshake=Noise_KKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625413c6b4c495bbc7b95432535cc6716834442ddae5e177d5bfd397 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466169cfd28ccd38213e17b518f78c70703c52b0d8d51d4479b557a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13f09ec7877b005731a876958cec004a7f9c2734e971828082db441ce001c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cf3a9cb9da7eb9bea19447b1f9bea60ac70124dfef886e9b82cd52f748c682 + +handshake=Noise_KKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f45eb20acd443feff46b315ad0366d803b7da09e6b84e12c1064 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d510ee9dd1b542ca5a0dca75e69bc396eea2dadec726382e2030 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96252868cb85131fc634b43f37c135da2b02902158369ec7a8e6b45b246732 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52822ad96c98c7ebcf68cafe91b6f18929aad75af5424a973cdb0f004b3832 + +handshake=Noise_KKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540590c32754712b9ce391bf35caa325f1ed107ec12d5cb4fc49af +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1bd851e93bfded9a6c776e0614d573731a40e7f562f6f3c067f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d219ab65f4416d18e67f501afa99f43009c0a1c2c78427b1dcbdd6cf020928 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1c6b3e31392287e06fcc5a885ea8690e39a2d3d54e23f5aeca14fca3c2f053 + +handshake=Noise_NX_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba1de7566c661eeed804d8fba1bcf3071d59a4a7ee2095ae6e8d813b554ad81ee45f4a4b6c2e8cd75b923c050e1330749b0c56fbae778fd91060bca3512061cf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=947e1b1a2798ef97094d7dbccd7244c92baf5e4d8b0e7ed5da78fbe1fdac76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed42482e9b09e2f97dc931e1444f9d7a8b51241108b41cab53474327500596 + +handshake=Noise_NXpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254600c4a8eb4f41bafda4465f2e9e34bae +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661aa7a9691509a04c46a6ce79f30fdbc377a2158ca3967df0ea4b1bb18532ca8737927e184c0605e9641bc3974b037282ceae988c87be4c68494c1d4f2b705cb2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=309e81a1ec83fd198e19b766e75f5e3a6ee55cd7b0119955211dcfcfdd0dae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=92ac33cb48df9677f9a6528346e17cd89855368535e8ee3c8252291d7820a4 + +handshake=Noise_NXpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b83011e8a447059f5a20533e49339a7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466afe68fdc6ad2df579fc8c4647c9daa9bccf146281b1fd8a0c4a193c206e89182236eb3f634d1c039759312597c6b3d48389b835f65abd51fd8e9a844fcfa9d89 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bd4ff6855a94bfd208d12eab8a615bd648d2e255bbca66ef2dcf95b6f64051 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=72f8827c79760073df771af24d5577a294e6c91391de79ad375277b91c899e + +handshake=Noise_NXpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c32f9f7340e786f655274b1d55dddeb1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466483412f9b4501d6e091c567f54851490683ba20583a2d46f9e46a34e1aef4d4f027e98fac3b55d80b833ac43e55d84d2597fbd6906b2ce5c0101b0c992bd7816 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4e6a4d111017cdfee460438955caf3234610c1971e06d1143ca16c7b407a96 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0f24650c4c6aa4a0ac25f0def8ac28890c64ad3bd787f101be1f6f3d868288 + +handshake=Noise_NX_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba1de7566c661eeed804d8fba1bcf3071d59a4a7ee2095ae6e8d813b554ad81e4ad1b2e3dc131f7decf35551aaa64803118efe076183e491cbc8dbfa9e20298f8603da282b6cbbf303c8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=947e1b1a2798ef97094d7dbccd7244c92baf5e4d8b0e7ed5da78fbe1fdac76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed42482e9b09e2f97dc931e1444f9d7a8b51241108b41cab53474327500596 + +handshake=Noise_NXpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dc8c612be768de5f7f3df631297f55b318248d15e3475c151d8d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661aa7a9691509a04c46a6ce79f30fdbc377a2158ca3967df0ea4b1bb18532ca87a13b25dfb83dac18a8cbac87c6bc6992ef497397067bba94fb3a96ca3a1020c00a2ae479f2e60e977d68 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=309e81a1ec83fd198e19b766e75f5e3a6ee55cd7b0119955211dcfcfdd0dae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=92ac33cb48df9677f9a6528346e17cd89855368535e8ee3c8252291d7820a4 + +handshake=Noise_NXpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547bb202abc57006587591d4d467cc7bcbd58800e3d148ce4963e9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466afe68fdc6ad2df579fc8c4647c9daa9bccf146281b1fd8a0c4a193c206e89182e71c52c2ee8ffc027ee7460754ec704fb0f338043a3e469bd74c850e7f4502269fd8e69922b3ec7f014c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bd4ff6855a94bfd208d12eab8a615bd648d2e255bbca66ef2dcf95b6f64051 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=72f8827c79760073df771af24d5577a294e6c91391de79ad375277b91c899e + +handshake=Noise_NXpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cb0e968d6f6cf4ffa7b1a168a144a90d468d117045bcdac9ce2b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466483412f9b4501d6e091c567f54851490683ba20583a2d46f9e46a34e1aef4d4f2f0c8a081791c4ee0f5abb8697ffc0c99562af1f3e104d1bc04df1b1a17a2ead35a5b569377336e90470 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4e6a4d111017cdfee460438955caf3234610c1971e06d1143ca16c7b407a96 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0f24650c4c6aa4a0ac25f0def8ac28890c64ad3bd787f101be1f6f3d868288 + +handshake=Noise_NX_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba1de7566c661eeed804d8fba1bcf3071d59a4a7ee2095ae6e8d813b554ad81e607b7c6987c60ff865c745b0c6ef765be0580f5484546cf94bd3ecb0d2298226 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=947e1b1a2798ef97094d7dbccd7244c92baf5e4d8b0e7ed5da78fbe1fdac76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed42482e9b09e2f97dc931e1444f9d7a8b51241108b41cab53474327500596 + +handshake=Noise_NXpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625470fd0f29b580ff883963cdee7776787b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661aa7a9691509a04c46a6ce79f30fdbc377a2158ca3967df0ea4b1bb18532ca87d439f889f15a1819502b8356523b4d3a14b3906db2105a3a567cecce7699b721 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=309e81a1ec83fd198e19b766e75f5e3a6ee55cd7b0119955211dcfcfdd0dae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=92ac33cb48df9677f9a6528346e17cd89855368535e8ee3c8252291d7820a4 + +handshake=Noise_NXpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ead4aca71459776346063860fc9dacef +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466afe68fdc6ad2df579fc8c4647c9daa9bccf146281b1fd8a0c4a193c206e8918205f730787beb926375b224bdd8c3ffd2b485a3a2e44ac9e33de0e3160438b266 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bd4ff6855a94bfd208d12eab8a615bd648d2e255bbca66ef2dcf95b6f64051 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=72f8827c79760073df771af24d5577a294e6c91391de79ad375277b91c899e + +handshake=Noise_NXpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549d596409946ef9c77e9c61aaeaaad31b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466483412f9b4501d6e091c567f54851490683ba20583a2d46f9e46a34e1aef4d4fd1622b6c789a6df165149281d1be9449a04338eb661d26528df109a269ed2a5d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4e6a4d111017cdfee460438955caf3234610c1971e06d1143ca16c7b407a96 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0f24650c4c6aa4a0ac25f0def8ac28890c64ad3bd787f101be1f6f3d868288 + +handshake=Noise_NX_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba1de7566c661eeed804d8fba1bcf3071d59a4a7ee2095ae6e8d813b554ad81eb15e8bfeea1d1766c1ca995bf2fc89f8118efe076183e491cbc8f2e50c3b6af6238ec0e37daffb0cc742 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=947e1b1a2798ef97094d7dbccd7244c92baf5e4d8b0e7ed5da78fbe1fdac76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed42482e9b09e2f97dc931e1444f9d7a8b51241108b41cab53474327500596 + +handshake=Noise_NXpsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dc8c612be768de5f7f3d2d79705307fcaf69908c306a29c5e2e2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661aa7a9691509a04c46a6ce79f30fdbc377a2158ca3967df0ea4b1bb18532ca87cd254354d4669c66db55d59ea0db0c57ef497397067bba94fb3a75d3a3b3804d73a62887f06cd31b17dc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=309e81a1ec83fd198e19b766e75f5e3a6ee55cd7b0119955211dcfcfdd0dae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=92ac33cb48df9677f9a6528346e17cd89855368535e8ee3c8252291d7820a4 + +handshake=Noise_NXpsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547bb202abc57006587591865999d0fba3fb1daa6f307a1c5a69b9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466afe68fdc6ad2df579fc8c4647c9daa9bccf146281b1fd8a0c4a193c206e89182883437826964719dfe774885fd82ed85b0f338043a3e469bd74c03833e4d31c6c4197118b2d0c23fe394 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bd4ff6855a94bfd208d12eab8a615bd648d2e255bbca66ef2dcf95b6f64051 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=72f8827c79760073df771af24d5577a294e6c91391de79ad375277b91c899e + +handshake=Noise_NXpsk2_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cb0e968d6f6cf4ffa7b18efe9bd452f1b893c8e960b8be69195b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466483412f9b4501d6e091c567f54851490683ba20583a2d46f9e46a34e1aef4d4fe228d02a04c8e97aca8ccf320bd8132d9562af1f3e104d1bc04dbc27c527aa4edf080cdd9962779f7718 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4e6a4d111017cdfee460438955caf3234610c1971e06d1143ca16c7b407a96 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0f24650c4c6aa4a0ac25f0def8ac28890c64ad3bd787f101be1f6f3d868288 + +handshake=Noise_KX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846651b9d60eb501f5efa797765be5facecd1b54777890c04bcbd4c363392ec8020c6574a4c4d6b72b0eb5e4f7ddfa581d58df144e59de159afb7c8c8c882873e8f6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cef18cc9c074b7b65b0876c13b23ac88a40d8f0508e88ce059511c69cafe8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2cb3ee4126b92633a230fa828a5d01e20577ad6957dbab9f547a0d321da1aa + +handshake=Noise_KXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fd769263bccd79587c7f736e1359352c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668140b6d6d8f57a44ea44a8faf051f109ab23fa8a11571923ab169aa41f1c145acaa50a4110b116973a047dc46fda6e45e79872d9a133db8635d3ef5f62c67f8c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=741d43d667af84da98ce714d05b47f025f58390989a6017c317d906d89cef3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=03cd0d03692885e37a8b0b6163e094c9a8d5a62383c15a0d43af0505985d69 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625494e6dc9266f412da8940e5f1ed2928a1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a0bfaa51f5148f03b052ef9bcbe0a78ff41c171a105e9928b8eca5683674c22961d70956f724006d7c2c5f64c58fcc8b9e6d7c434b2bc8dfe67a122758b866ed +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=57271ed33c4dc921dde89c5e7920df0ab2a58361b19e4d6383e650da99e7fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4719d03ef8bd3d51202cb10d97d8ed9a449b928b50944e20fc749fdd36882a + +handshake=Noise_KXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9c7f6571bb640878ca69055b410af39 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664eb43ac79c1a09d29d9ee9abd60d01f24e07f95c9b57e6b228513d3b911a6bc5ad29b67154c895c55dca9525049a9c88bb1d43a542bd18b0ad443deb912abfdd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=97fb83aaf881a57aef8a2ee5c92067bfb12be1ca9ff96ec05801a17ab59dc1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5980f6c58e2c33192316ff9db9684a41f98cff4c921dd99d10a147888cab96 + +handshake=Noise_KX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846651b9d60eb501f5efa797765be5facecd1b54777890c04bcbd4c363392ec8020cffea7b7816cc8d3cbba422da8c5039188ad2715f430663cbef349f687f0f01cc0840853c3dd4a03ce7bc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cef18cc9c074b7b65b0876c13b23ac88a40d8f0508e88ce059511c69cafe8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2cb3ee4126b92633a230fa828a5d01e20577ad6957dbab9f547a0d321da1aa + +handshake=Noise_KXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625479403368521b32d522b60c39847630ecef1bd89c190bd2cb44fb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668140b6d6d8f57a44ea44a8faf051f109ab23fa8a11571923ab169aa41f1c145a32241706d4690b505402baf8a06ac03dc72401f783edd06f26aaa98ca33150b3f574651a160baec40c13 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=741d43d667af84da98ce714d05b47f025f58390989a6017c317d906d89cef3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=03cd0d03692885e37a8b0b6163e094c9a8d5a62383c15a0d43af0505985d69 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625456816aec771748a363fa2a63e3ea0a5168ce09326a42f6efc8b8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a0bfaa51f5148f03b052ef9bcbe0a78ff41c171a105e9928b8eca5683674c229549745c7795addacbbf9c25b7cc5137f185ab372ec13f203d0fe6467406ad4cc76392bb4aee1f7c753b8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=57271ed33c4dc921dde89c5e7920df0ab2a58361b19e4d6383e650da99e7fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4719d03ef8bd3d51202cb10d97d8ed9a449b928b50944e20fc749fdd36882a + +handshake=Noise_KXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625403f860c4b0e5d136c74ff866a7ebba59b63ddf4984282f9a193c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664eb43ac79c1a09d29d9ee9abd60d01f24e07f95c9b57e6b228513d3b911a6bc58b6457503d60ae02750d4fddc6a3866ed9e2b7b665ba695e83536460bf805b4ed26df8efe3af02fd4d67 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=97fb83aaf881a57aef8a2ee5c92067bfb12be1ca9ff96ec05801a17ab59dc1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5980f6c58e2c33192316ff9db9684a41f98cff4c921dd99d10a147888cab96 + +handshake=Noise_KX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846651b9d60eb501f5efa797765be5facecd1b54777890c04bcbd4c363392ec8020c59dd8e8bebc235878d857c6d84f0a5338eb5d49142fed0d622590da2f9ea200d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cef18cc9c074b7b65b0876c13b23ac88a40d8f0508e88ce059511c69cafe8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2cb3ee4126b92633a230fa828a5d01e20577ad6957dbab9f547a0d321da1aa + +handshake=Noise_KXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540fbdb18c265d797f42d7536d571f3473 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668140b6d6d8f57a44ea44a8faf051f109ab23fa8a11571923ab169aa41f1c145ad1708830ccf11c7e12c15ae550ba6b9ce92e7a01beb8af9f1ce00af37806dd10 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=741d43d667af84da98ce714d05b47f025f58390989a6017c317d906d89cef3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=03cd0d03692885e37a8b0b6163e094c9a8d5a62383c15a0d43af0505985d69 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546046313eb7d85b39691f62081c58167c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a0bfaa51f5148f03b052ef9bcbe0a78ff41c171a105e9928b8eca5683674c229fc6c0e0e58ca821feb64676b38238320161795720ff76f68a12f005fcb10d883 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=57271ed33c4dc921dde89c5e7920df0ab2a58361b19e4d6383e650da99e7fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4719d03ef8bd3d51202cb10d97d8ed9a449b928b50944e20fc749fdd36882a + +handshake=Noise_KXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b60f0d634971bb203b652ba1967b61a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664eb43ac79c1a09d29d9ee9abd60d01f24e07f95c9b57e6b228513d3b911a6bc5e426a250b6d1851e0988cc7e1e3d719f9b071823a8e301e71894a3e769e1e9fa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=97fb83aaf881a57aef8a2ee5c92067bfb12be1ca9ff96ec05801a17ab59dc1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5980f6c58e2c33192316ff9db9684a41f98cff4c921dd99d10a147888cab96 + +handshake=Noise_KX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846651b9d60eb501f5efa797765be5facecd1b54777890c04bcbd4c363392ec8020c7c436998be9c91ef0b5bf378deb15d158ad2715f430663cbef34c07c8fffbbe6e1d06b86643854167c10 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cef18cc9c074b7b65b0876c13b23ac88a40d8f0508e88ce059511c69cafe8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2cb3ee4126b92633a230fa828a5d01e20577ad6957dbab9f547a0d321da1aa + +handshake=Noise_KXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625479403368521b32d522b66108a91f0ee0630b01d5e9d75894e97b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668140b6d6d8f57a44ea44a8faf051f109ab23fa8a11571923ab169aa41f1c145a15a68caffb32e07426fb150508d5a8edc72401f783edd06f26aa8076fe78659e21041dd0d33c189cefe9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=741d43d667af84da98ce714d05b47f025f58390989a6017c317d906d89cef3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=03cd0d03692885e37a8b0b6163e094c9a8d5a62383c15a0d43af0505985d69 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625456816aec771748a363fa549a17755a6b8c1bd2ba5e506be3c0ad +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a0bfaa51f5148f03b052ef9bcbe0a78ff41c171a105e9928b8eca5683674c22927af6ddc7a690cdb4d5a2980f751f89a185ab372ec13f203d0fea95291c45a6bd1ecd8d7646b9d8232d1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=57271ed33c4dc921dde89c5e7920df0ab2a58361b19e4d6383e650da99e7fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4719d03ef8bd3d51202cb10d97d8ed9a449b928b50944e20fc749fdd36882a + +handshake=Noise_KXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625403f860c4b0e5d136c74f34c13ce247013edb3c379e4a24ac14df +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664eb43ac79c1a09d29d9ee9abd60d01f24e07f95c9b57e6b228513d3b911a6bc5668549e52bbb134d9ff2d80daea26b9dd9e2b7b665ba695e83538dfe52c654f53bcdc88eea727bffe4ce +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=97fb83aaf881a57aef8a2ee5c92067bfb12be1ca9ff96ec05801a17ab59dc1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5980f6c58e2c33192316ff9db9684a41f98cff4c921dd99d10a147888cab96 + +handshake=Noise_XN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661b40ea2c38a51f959025c4dccfa89109 +msg_2_payload= +msg_2_ciphertext=503a8b472892ad3f5b51559452113c16ed3e184c13f944444437a34e31f439ff6700164dde01a283d026e511c871c6f0e8020d7872c914f667606b55934e2e99 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6233ac2185ec7af41983156d39699d8449548f0b481d6d0749496ffa362e5e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=085d31a2a8dfa0451b2080d1b516bf21503bd2abba540af2b97baad8ac7d60 + +handshake=Noise_XNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254be60dc15acd4d448e54a81c36031b2bd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f001d2d0138680be35a3b247be41ddf9 +msg_2_payload= +msg_2_ciphertext=644acc467adf3b0fcf528112daa6473b5f7eccfda6f35e43c8ceacc5b36fdbe783cb198473d625c010ec9b15dbc16f4f484ee5e9afd0030c14ad672c27888cc5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=89cbd646aeb2f177e721951f251ba49fa3301858d90e126b2624f075d4f129 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20943736018249bb86246c5e6abc05a43318177fd1acf9f17fdbe66f0c8786 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541b7a6a865a363291e581c34bc35c8365 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b37f01c70f05506d6dac3d469cf12970 +msg_2_payload= +msg_2_ciphertext=b6247d8e9b00e51c28e179223285ba39a6d8a8cf6e9d30da6d45046a5bcc46ead5bd76c082595e3fa851fa68b226fed2f0e36857ce2b2c1bb6db5d1def71c553 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8823a52a7820f4427e8bd2d71aee13f17e979b1095e2602f212c1a0fde7f8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed15c9431df4f8e30c7d69d8fcc1f3cba62eff9b8f0dca8439b1e63185873e + +handshake=Noise_XNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542d0c7264b68d5dc48dec2efebac21eb5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666ccb5e6f7f8a43fcc7c08ceb60ebd6dd +msg_2_payload= +msg_2_ciphertext=87cb6974ecc3d5ae746b5ad5a13889eeb64930c8b2d75ab050cea76ff88b0daf2cdaeaedd0347d1e3ea45daae0d82d651f6e5570c6f9ffb03740c5029abbd1d9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=da8087eb4a0c87e6500c27c335fa688af01ce4ab4293ae99bd8457b38d33c2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7e8a728afbddb6786dcead1803d0a8cefb780f66989efcc00512c0c0b84e86 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a3b49c63b28e53c4ca60d9665141307f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663354690faf83da25e878325a2005f1c9 +msg_2_payload= +msg_2_ciphertext=f63edbeb454c2df86a311f7f3d7491fe197f6d6afa7a23b1c875ba31c93d2941a13e8327f351cec361b5967dab1ea7ce283091fe45f7139d7632d9a3d927737a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=54db3e36bce2d3a19395309650bd3014b7e71eb3f2708a2b13adee825d2577 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb8ea9164c2c727cbdab7ad21c485b2fd73d7dbe30d39482241ab93994aea2 + +handshake=Noise_XN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846612f372d7f26b78d4c7c9c9f08c104df736cc02ea331c83c6498d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=503a8b472892ad3f5b51559452113c16ed3e184c13f944444437a34e31f439ff87991616ec896946bdfd5a2ff7ecab30b1d5d90b0180e4020e32b2905fa1fdf1abf0e17903d0fa11bd8d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6233ac2185ec7af41983156d39699d8449548f0b481d6d0749496ffa362e5e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=085d31a2a8dfa0451b2080d1b516bf21503bd2abba540af2b97baad8ac7d60 + +handshake=Noise_XNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625405e10984cac2c8b9431e3e5025938df4e39c942478bcc2722a54 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664981c8d4906f552b923dffdde5a30fb4fd30cceb9091ef913503 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=644acc467adf3b0fcf528112daa6473b5f7eccfda6f35e43c8ceacc5b36fdbe77f7303d2484e680d0dcf1703bd006df162029804a05248513696b861f3a2d2627f36c2cb683bbbf99ddd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=89cbd646aeb2f177e721951f251ba49fa3301858d90e126b2624f075d4f129 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20943736018249bb86246c5e6abc05a43318177fd1acf9f17fdbe66f0c8786 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c524c8eec1e25e136d78dc60a45cf7fb50893415f65319efb637 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466428012d547892abee56b6fc69ba0315682828117b88eb1fdab61 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b6247d8e9b00e51c28e179223285ba39a6d8a8cf6e9d30da6d45046a5bcc46eabecda5d2c25c7b10b66f093bf41749a97a849041926ab49c36be5cadaf10f95a92bd053872927102b2d5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8823a52a7820f4427e8bd2d71aee13f17e979b1095e2602f212c1a0fde7f8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed15c9431df4f8e30c7d69d8fcc1f3cba62eff9b8f0dca8439b1e63185873e + +handshake=Noise_XNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254785623d13d7d90f0389866c83a7a233d82456b10229518acb15b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d20b83210dbf4e12a39779088407fd878b5cee5e2b6f76a833ac +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=87cb6974ecc3d5ae746b5ad5a13889eeb64930c8b2d75ab050cea76ff88b0daf4fcff82bc91dec08d2fdc0da7c49231e2861bb4a561c81a29395619f3a27ba934977dc7d0a1334dbf516 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=da8087eb4a0c87e6500c27c335fa688af01ce4ab4293ae99bd8457b38d33c2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7e8a728afbddb6786dcead1803d0a8cefb780f66989efcc00512c0c0b84e86 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e23359ef5f50e0c7c53b5611a0d5eba739ae40af2b928c454691 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663c23b78afaf9c3b0446d9fa54f1e1f8f7d2f79e8c53500e85fcc +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f63edbeb454c2df86a311f7f3d7491fe197f6d6afa7a23b1c875ba31c93d294145cee44b4f3577448b2097fb2e75b732499943c385cd7d2e878c8b49fb5e7ccbb54cc89cd47e5e0b68c9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=54db3e36bce2d3a19395309650bd3014b7e71eb3f2708a2b13adee825d2577 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb8ea9164c2c727cbdab7ad21c485b2fd73d7dbe30d39482241ab93994aea2 + +handshake=Noise_XN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e7d5bc062725904d0e112526293811b9 +msg_2_payload= +msg_2_ciphertext=503a8b472892ad3f5b51559452113c16ed3e184c13f944444437a34e31f439ff302f7d08f2b456cefb4b1898b3d59dc7b2c227d1b5776db819a910a3ada6f410 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6233ac2185ec7af41983156d39699d8449548f0b481d6d0749496ffa362e5e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=085d31a2a8dfa0451b2080d1b516bf21503bd2abba540af2b97baad8ac7d60 + +handshake=Noise_XNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f1aa09b43530ef5ef8da92a470629df9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665e93ce32ae9ed58913085363e1d5a366 +msg_2_payload= +msg_2_ciphertext=644acc467adf3b0fcf528112daa6473b5f7eccfda6f35e43c8ceacc5b36fdbe7e560c143da89678734b80155a6ffa08c02183ae0fa0cfb2ee8a2bd6576b2c8e7 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=89cbd646aeb2f177e721951f251ba49fa3301858d90e126b2624f075d4f129 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20943736018249bb86246c5e6abc05a43318177fd1acf9f17fdbe66f0c8786 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dbdd21afbcb5201f3293e6b9b0b21741 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846619cb4d03a0688af431c043c964cc5d0c +msg_2_payload= +msg_2_ciphertext=b6247d8e9b00e51c28e179223285ba39a6d8a8cf6e9d30da6d45046a5bcc46ea39962cc6c99fbf9cb381353ee8374245874d4c279a323370bbb6373a8a000e16 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8823a52a7820f4427e8bd2d71aee13f17e979b1095e2602f212c1a0fde7f8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed15c9431df4f8e30c7d69d8fcc1f3cba62eff9b8f0dca8439b1e63185873e + +handshake=Noise_XNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b1bd021ed3e3e5d4807ada02f9645d74 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692b94bc6537d2fed9a3c770b66591637 +msg_2_payload= +msg_2_ciphertext=87cb6974ecc3d5ae746b5ad5a13889eeb64930c8b2d75ab050cea76ff88b0daf415213045fc25050c65d660b1e1b6a8589a8c628892a21e02b5c3f0ea78c5e9f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=da8087eb4a0c87e6500c27c335fa688af01ce4ab4293ae99bd8457b38d33c2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7e8a728afbddb6786dcead1803d0a8cefb780f66989efcc00512c0c0b84e86 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c583a80c1b9c72ff4fcab5c6642a61b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d97987c73974b0eaf6f990ab6e715b69 +msg_2_payload= +msg_2_ciphertext=f63edbeb454c2df86a311f7f3d7491fe197f6d6afa7a23b1c875ba31c93d294125e1b2c36a4607e8a34670736750fee5ac7d0a002482b07d7cc4a69115c88d30 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=54db3e36bce2d3a19395309650bd3014b7e71eb3f2708a2b13adee825d2577 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb8ea9164c2c727cbdab7ad21c485b2fd73d7dbe30d39482241ab93994aea2 + +handshake=Noise_XN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846612f372d7f26b78d4c7c93deca890b478737fefc1db77d4a70c7d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=503a8b472892ad3f5b51559452113c16ed3e184c13f944444437a34e31f439ffb3cda7ae4d197b2eba686c6de1039e57b1d5d90b0180e4020e325aade631cb7d75d78cb7a4be982b0e4a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6233ac2185ec7af41983156d39699d8449548f0b481d6d0749496ffa362e5e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=085d31a2a8dfa0451b2080d1b516bf21503bd2abba540af2b97baad8ac7d60 + +handshake=Noise_XNpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625405e10984cac2c8b9431ef429d0a9e1e987fa9ab72ed768d453d2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664981c8d4906f552b923d648b1adfd98463b7de620c3809e54270 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=644acc467adf3b0fcf528112daa6473b5f7eccfda6f35e43c8ceacc5b36fdbe7befd4b86277538e5733008c9b549f39962029804a0524851369631704b259e55bf9c511ac01893651c08 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=89cbd646aeb2f177e721951f251ba49fa3301858d90e126b2624f075d4f129 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20943736018249bb86246c5e6abc05a43318177fd1acf9f17fdbe66f0c8786 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c524c8eec1e25e136d780cd029d91adbe0f2524363dd016b477d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466428012d547892abee56b0265f0c9fe99b596e2291d0a3d9d0d3e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b6247d8e9b00e51c28e179223285ba39a6d8a8cf6e9d30da6d45046a5bcc46ea33c71af82b774d8fb8295a28eef160217a849041926ab49c36be63429a9c3a37f6fe3914421b8a79e348 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8823a52a7820f4427e8bd2d71aee13f17e979b1095e2602f212c1a0fde7f8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed15c9431df4f8e30c7d69d8fcc1f3cba62eff9b8f0dca8439b1e63185873e + +handshake=Noise_XNpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254785623d13d7d90f03898f7fee58afe50dae23444110a6e7e9cd0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d20b83210dbf4e12a3972ece13ca75b4160abaac01fb0cbdbcbd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=87cb6974ecc3d5ae746b5ad5a13889eeb64930c8b2d75ab050cea76ff88b0dafb71f25d3022bce2ac10652c064ebf0d32861bb4a561c81a29395a72e17a57f370259c04f0d0cb3899d80 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=da8087eb4a0c87e6500c27c335fa688af01ce4ab4293ae99bd8457b38d33c2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7e8a728afbddb6786dcead1803d0a8cefb780f66989efcc00512c0c0b84e86 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e23359ef5f50e0c7c53b7d4820e2923b0f9f60feec7466841622 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663c23b78afaf9c3b0446d2b9018a12da1972a41e5aca5b0374147 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f63edbeb454c2df86a311f7f3d7491fe197f6d6afa7a23b1c875ba31c93d2941b0f3595d303a638fc757eb81d7841a4a499943c385cd7d2e878c8d0d9ef63936a3804cdc64aabd99e829 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=54db3e36bce2d3a19395309650bd3014b7e71eb3f2708a2b13adee825d2577 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb8ea9164c2c727cbdab7ad21c485b2fd73d7dbe30d39482241ab93994aea2 + +handshake=Noise_IN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cdeb70e577c726fba1c682d0cc9d58dc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=942a03a9fbd149d80f827d68acb020b98a2988435155931aa6e87780e1ae0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6c22a69895e4c940bed283b9a10ce57d83f09683827a283fda77d75d086c6e + +handshake=Noise_INpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547c265cb3ca07c422159c05da5508b509330a9d97d67a3a8fea09e53fe4965fa404a45a7a007c03ec5b18911e3e5a11d686325db0c406eac3d84e1e705cd7e1c0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846669eeb99c25d0285113c571b33c777dc2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=702284b311f0bab378528420b7a5a4e829737ee3e6daf41517fda5fdfeadfb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52c5ed9e8e2fe3bb2a870b47b1380ef94a8578d3a895f4e799720902699fca + +handshake=Noise_INpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d56bb0c1876cf3c43d9e4704c3695912692be106f89aefc5f9a82faa4b8ed6d21fd0416e483d32cc8774dfcfdd0d384b277fc77f8a612755a568224a86f48e6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846610fab43afb44de3edfc9d3039020a09b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=594ecdb1619d52ce6094d23485ce71d1ba806bb3297be3e2aa8031b51f3fb9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=703336a1f5ae2eff07442bbbe4797fb864c8038a890332e943234fe11e92e7 + +handshake=Noise_INpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9b90bf88a0b8849c338ddcba137cc03b951bd2dc177071ee618d38f18d8171576e80df2eb20134ea61ecca66d604826193d3940232859387a7e6ab57d74bb41 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665f13b26b4e47f377f079cba555e2c2e7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c8cda123eca519ddae68fd5de69ae61696a8147e06b1b057478de9ca4dd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=477468334e5fe3fd833bedbdaa22c7030e03eb531402dd48df9ce98182ef08 + +handshake=Noise_IN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e081945b5d5301fe42dadb6da0f788260c6252af7f41e986c5c2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=942a03a9fbd149d80f827d68acb020b98a2988435155931aa6e87780e1ae0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6c22a69895e4c940bed283b9a10ce57d83f09683827a283fda77d75d086c6e + +handshake=Noise_INpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547c265cb3ca07c422159c05da5508b509330a9d97d67a3a8fea09e53fe4965fa404a45a7a007c03ec5b18911e3e5a11d609022778b13fa7b2d13986844231dd445a7fdf2deced73ed7dc6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466245acc39d32cd111269cd3b4981cd32d0fc1dd3dbcd10c2ccd00 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=702284b311f0bab378528420b7a5a4e829737ee3e6daf41517fda5fdfeadfb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52c5ed9e8e2fe3bb2a870b47b1380ef94a8578d3a895f4e799720902699fca + +handshake=Noise_INpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d56bb0c1876cf3c43d9e4704c3695912692be106f89aefc5f9a82faa4b8ed6d21fd0416e483d32cc8774dfcfdd0d3849494d756adea0eee2f87617f98ac7dedd0342f13f2437853cac6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb85a80b70fd80c7647ad87182859bce0d29d69890b8fddcad49 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=594ecdb1619d52ce6094d23485ce71d1ba806bb3297be3e2aa8031b51f3fb9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=703336a1f5ae2eff07442bbbe4797fb864c8038a890332e943234fe11e92e7 + +handshake=Noise_INpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9b90bf88a0b8849c338ddcba137cc03b951bd2dc177071ee618d38f18d8171576e80df2eb20134ea61ecca66d60482696650307415ef3e84d9de5db5ddbb0c6edb37e0652d8f8a58b7b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bda119e70ff1a807b1f5c259b407bd4480b60a637c4e94aed69b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c8cda123eca519ddae68fd5de69ae61696a8147e06b1b057478de9ca4dd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=477468334e5fe3fd833bedbdaa22c7030e03eb531402dd48df9ce98182ef08 + +handshake=Noise_IN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b8070f1a05f109f179e7d3cb6327b9ff +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=942a03a9fbd149d80f827d68acb020b98a2988435155931aa6e87780e1ae0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6c22a69895e4c940bed283b9a10ce57d83f09683827a283fda77d75d086c6e + +handshake=Noise_INpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547c265cb3ca07c422159c05da5508b509330a9d97d67a3a8fea09e53fe4965fa459403c6046385d6af1f458771895e2fab6c321b290160c5bd68c6a7c621388ad +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661e03dc287297fc7ff86bc8c7810284ea +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=702284b311f0bab378528420b7a5a4e829737ee3e6daf41517fda5fdfeadfb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52c5ed9e8e2fe3bb2a870b47b1380ef94a8578d3a895f4e799720902699fca + +handshake=Noise_INpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d56bb0c1876cf3c43d9e4704c3695912692be106f89aefc5f9a82faa4b8ed6d83c17fa055704307c8811d1b0e0ad295f02971305459fdd7f965b0feb5b7ab6b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846628f89ed04b07e0e9e94742792dc39554 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=594ecdb1619d52ce6094d23485ce71d1ba806bb3297be3e2aa8031b51f3fb9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=703336a1f5ae2eff07442bbbe4797fb864c8038a890332e943234fe11e92e7 + +handshake=Noise_INpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9b90bf88a0b8849c338ddcba137cc03b951bd2dc177071ee618d38f18d8171506626ab4985988f259d4b3030f1cecd90c4c6d1aa93d4213ad6adf172946bd3e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663096c40b47d26caec9bce34e223bc3db +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c8cda123eca519ddae68fd5de69ae61696a8147e06b1b057478de9ca4dd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=477468334e5fe3fd833bedbdaa22c7030e03eb531402dd48df9ce98182ef08 + +handshake=Noise_IN_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e081945b5d5301fe42dabcc010cb04cf66f06d25106d39cc52c8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=942a03a9fbd149d80f827d68acb020b98a2988435155931aa6e87780e1ae0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6c22a69895e4c940bed283b9a10ce57d83f09683827a283fda77d75d086c6e + +handshake=Noise_INpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547c265cb3ca07c422159c05da5508b509330a9d97d67a3a8fea09e53fe4965fa459403c6046385d6af1f458771895e2fa09022778b13fa7b2d1391f421b1293b7d5da70d030b158d7cc98 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466245acc39d32cd111269c53d0795705caaf644f5bd95501f560b9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=702284b311f0bab378528420b7a5a4e829737ee3e6daf41517fda5fdfeadfb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=52c5ed9e8e2fe3bb2a870b47b1380ef94a8578d3a895f4e799720902699fca + +handshake=Noise_INpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d56bb0c1876cf3c43d9e4704c3695912692be106f89aefc5f9a82faa4b8ed6d83c17fa055704307c8811d1b0e0ad2959494d756adea0eee2f8785d82292d8f8ed078e246a2fb78d65e1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb85a80b70fd80c7647ae5822e9159b0bef8a8d773460386dc8b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=594ecdb1619d52ce6094d23485ce71d1ba806bb3297be3e2aa8031b51f3fb9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=703336a1f5ae2eff07442bbbe4797fb864c8038a890332e943234fe11e92e7 + +handshake=Noise_INpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9b90bf88a0b8849c338ddcba137cc03b951bd2dc177071ee618d38f18d8171506626ab4985988f259d4b3030f1cecd996650307415ef3e84d9d01a03ce746f46e4a8128825ca5788c4a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bda119e70ff1a807b1f540d5adbfebb77d74f37e87a47d4df9a0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c8cda123eca519ddae68fd5de69ae61696a8147e06b1b057478de9ca4dd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=477468334e5fe3fd833bedbdaa22c7030e03eb531402dd48df9ce98182ef08 + +handshake=Noise_XK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c050317e287f01c5a4a9f6f37a94856a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea8cc87b9a11903d7f303d57269ff01c +msg_2_payload= +msg_2_ciphertext=065a23c2f62fb1bed15cb6ecbd9267c0dc7524d31ee9367258f443517df4b46717fa1a7d40a1fe3f74d4072a798f56f68670975962e5e284bdbc195ce67b8083 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7043c98fbdd02d209268778851ae3117aa9cb3b29737867eb75e0718e8acfa +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=21069488a4bddda5c5211d9c5b80c1c5e42c4e65e5cd3040c613272ac05c07 + +handshake=Noise_XKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f2190213b518df1b9dc5abd926f7f12e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664beb6a04f3934e2aa1ce0eecdac1fda7 +msg_2_payload= +msg_2_ciphertext=f2fccf5e2aa6632808766b744399eb8a442020fcc5d2a516b5faa1a6b3561ca556b896b594f7c06e6228c1e05d4a3d1cc6c648d7bafbf389b519577c9a89945d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c18790dcb28ed5ebef55be13986db9dd2b9ed2133da67d370de3f1334ac9fc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=808fe9194364bc33125f5a83c2cece78bbc1e85d7eabbc015dbd9b661e8a75 + +handshake=Noise_XKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625486461e79ac43ef4a2cfea92f000ded06 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846602646e9b0c0f3a8cdf4bb57b005e9237 +msg_2_payload= +msg_2_ciphertext=f67e4c95336d43f8f72939e99f678331124ae5f5d9bd5e40a41ddded5a0a1b12ede3d82b8736b89315c15e0f4afeef04516b890c51b8302bb5a325bec3ecfba9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5b12ab52b1ee79a1114c3407e153f320863dfc86a0d98764f62651c50e2ede +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c5f2aed3a22d04a2107aca55f25a31366bc246ed6b52d3e71a413409d3e1ce + +handshake=Noise_XKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d5b4ca0da34839493aa0ac72dd63d23b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466805f13e0cb0646004ef00f7da87a5766 +msg_2_payload= +msg_2_ciphertext=0bb72e926efbf321955a792b7ccb45a295c6d5f031f59648c9662b709a8df50723987232b9f4da9ca839b69be56589a440adc771cc7e3c6f62aefb962d0ca355 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=974c226eca2032beaa7dc8e9ee1ac58e566cb305fbc79cca8ffa77eb6a02d0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94e1425470776282f7e9751698cc7ba2ae5dc0cb3c8d9b189021f6b94e65ec + +handshake=Noise_XKpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fe849be95b0f77879a684979c7af0544 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846682d5e55e0f9af1439418f4fbd8f974e2 +msg_2_payload= +msg_2_ciphertext=c1a1778bfba62342d38b2dc7c5042d7e809efc74a6d780d2d7589673e27a3a1a31e539e0855f6ea1b0ff3d61a12da8e10959cb26e02e0815e3ec5a58808352ae +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f4b75252b4249d95ebbc815bee87953b2bc4d6bc1ca89237d9196ab363b7fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f0a47d13ace24e87f0b5319eea0bc141a410d4d1ae2705e4a0dc5fd168c867 + +handshake=Noise_XK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254496dd4fd65bcb73030e1a50f16936b093497a8bde429c662e917 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea95f04183becb2895dabdafa5b7d048a62812a4cdc993d14f40 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=065a23c2f62fb1bed15cb6ecbd9267c0dc7524d31ee9367258f443517df4b467b299f23b7566cb23e20882c3ec1a0f6aad26e0baa7ec90d7741c99f08177caf8918d56c694da03de81bd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7043c98fbdd02d209268778851ae3117aa9cb3b29737867eb75e0718e8acfa +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=21069488a4bddda5c5211d9c5b80c1c5e42c4e65e5cd3040c613272ac05c07 + +handshake=Noise_XKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542423e50f21aff9ad1af4d952df961bc129edc38ab98728a8e058 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846654da6d875f5739c5ad31fb962eb44d8e77fb94b5bf87722578a6 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f2fccf5e2aa6632808766b744399eb8a442020fcc5d2a516b5faa1a6b3561ca5b56f60bb281bd60c6cb5312f4584d043b1d0c753b4af23154da6f47b34d3b8e7aca54c7dfbf9f8f14796 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c18790dcb28ed5ebef55be13986db9dd2b9ed2133da67d370de3f1334ac9fc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=808fe9194364bc33125f5a83c2cece78bbc1e85d7eabbc015dbd9b661e8a75 + +handshake=Noise_XKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545e026b56dc562c44666a4b04568f0485cef1c5067b4484d10d7c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466020430cef83f07cba7618e4b4de18d8f43a09e70021b8d5c701d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f67e4c95336d43f8f72939e99f678331124ae5f5d9bd5e40a41ddded5a0a1b12a73c4e9ad20e003306bf0682e5c662c2eadb761ca33e775aea82e39bce172ef4fdf75a28142fc4375066 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5b12ab52b1ee79a1114c3407e153f320863dfc86a0d98764f62651c50e2ede +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c5f2aed3a22d04a2107aca55f25a31366bc246ed6b52d3e71a413409d3e1ce + +handshake=Noise_XKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625429519d9da85dd8bb5090f154872c67bb1a86e0ecd5dc14d0dd77 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f4d74c505f803c540657f2f648cf45b3ec7222c71c4d9b8574e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=0bb72e926efbf321955a792b7ccb45a295c6d5f031f59648c9662b709a8df5075091175fc7e05098a89b8eb66fcbcc153ceb21a2f48b1ad5b7f41c741e6ebde723a3f28fa1cdca225fdd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=974c226eca2032beaa7dc8e9ee1ac58e566cb305fbc79cca8ffa77eb6a02d0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94e1425470776282f7e9751698cc7ba2ae5dc0cb3c8d9b189021f6b94e65ec + +handshake=Noise_XKpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a6f963df7b04718a9a3aecf6f1900be93d1d923389bd9009f140 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a13bb0d71fd337f74bd5d2c13987667845b0ac7dc84cdbc516c1 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c1a1778bfba62342d38b2dc7c5042d7e809efc74a6d780d2d7589673e27a3a1a27c2812e02c1c55e91c5143c3dc09ec208eab30f236b34955872b84b93506853f91d7e0a0fa565b63612 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f4b75252b4249d95ebbc815bee87953b2bc4d6bc1ca89237d9196ab363b7fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f0a47d13ace24e87f0b5319eea0bc141a410d4d1ae2705e4a0dc5fd168c867 + +handshake=Noise_XK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254adeaa7a4d551515273fda940aa4a5c8a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ef86a45510611db0c587343c9bc1598a +msg_2_payload= +msg_2_ciphertext=065a23c2f62fb1bed15cb6ecbd9267c0dc7524d31ee9367258f443517df4b467af8e83092060a7ae3419acc16ff01de79bd94e38a1517cc2bec944e49148c8fb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7043c98fbdd02d209268778851ae3117aa9cb3b29737867eb75e0718e8acfa +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=21069488a4bddda5c5211d9c5b80c1c5e42c4e65e5cd3040c613272ac05c07 + +handshake=Noise_XKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254629272b173021b86c6bb347f567e0a6f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466173b83666da49fc7fd72ff392de6600b +msg_2_payload= +msg_2_ciphertext=f2fccf5e2aa6632808766b744399eb8a442020fcc5d2a516b5faa1a6b3561ca51e31645083c4afd11906f23987a4afbf39430cf3f5285787fa12bff00fd46615 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c18790dcb28ed5ebef55be13986db9dd2b9ed2133da67d370de3f1334ac9fc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=808fe9194364bc33125f5a83c2cece78bbc1e85d7eabbc015dbd9b661e8a75 + +handshake=Noise_XKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bf1c11388fc68b4c1d166db401a26682 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669560df6a9977cbf93d0a0cea6aa07b63 +msg_2_payload= +msg_2_ciphertext=f67e4c95336d43f8f72939e99f678331124ae5f5d9bd5e40a41ddded5a0a1b128dce5e889350cf0ab7bdddbb06a6751c2f2c12b5cf714cf4d2e18eece5562d83 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5b12ab52b1ee79a1114c3407e153f320863dfc86a0d98764f62651c50e2ede +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c5f2aed3a22d04a2107aca55f25a31366bc246ed6b52d3e71a413409d3e1ce + +handshake=Noise_XKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9fe5233a2995e81a524c16aad452566 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466071dd09d6ce273e11d8798d8b12d2ce9 +msg_2_payload= +msg_2_ciphertext=0bb72e926efbf321955a792b7ccb45a295c6d5f031f59648c9662b709a8df50744a858e35dc73078e6dddca9a9697eb0dfc90b9ed958f8f0655807591acea472 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=974c226eca2032beaa7dc8e9ee1ac58e566cb305fbc79cca8ffa77eb6a02d0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94e1425470776282f7e9751698cc7ba2ae5dc0cb3c8d9b189021f6b94e65ec + +handshake=Noise_XKpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9f5585baf18efad7e93d7dec1071901 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a99a71b8f92e54977d070f1f10271671 +msg_2_payload= +msg_2_ciphertext=c1a1778bfba62342d38b2dc7c5042d7e809efc74a6d780d2d7589673e27a3a1a730cd354af59adfbfa3e6ec4bd08bc99aff4955676fbde51360f35a9a510f72b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f4b75252b4249d95ebbc815bee87953b2bc4d6bc1ca89237d9196ab363b7fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f0a47d13ace24e87f0b5319eea0bc141a410d4d1ae2705e4a0dc5fd168c867 + +handshake=Noise_XK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254496dd4fd65bcb73030e122934282a79fa89a268ffff61fb58356 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea95f04183becb2895daa2e377fc2cb1b7500945abce23064a11 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=065a23c2f62fb1bed15cb6ecbd9267c0dc7524d31ee9367258f443517df4b46762a479a461f55eba0779622a07538dabad26e0baa7ec90d7741c5aa49162b67b7a86591ed7080b6b60f6 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7043c98fbdd02d209268778851ae3117aa9cb3b29737867eb75e0718e8acfa +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=21069488a4bddda5c5211d9c5b80c1c5e42c4e65e5cd3040c613272ac05c07 + +handshake=Noise_XKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542423e50f21aff9ad1af4c5a676bf5dc0f8a46df2ed5acfecfae6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846654da6d875f5739c5ad31647583fd0cf33e43619573396b31e006 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f2fccf5e2aa6632808766b744399eb8a442020fcc5d2a516b5faa1a6b3561ca54e6e5e30d1fd0fa830ee2ce7be13e55ab1d0c753b4af23154da6432ba9b1bde756e4eba9c12bfb132acd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c18790dcb28ed5ebef55be13986db9dd2b9ed2133da67d370de3f1334ac9fc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=808fe9194364bc33125f5a83c2cece78bbc1e85d7eabbc015dbd9b661e8a75 + +handshake=Noise_XKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545e026b56dc562c44666a0b32c0f7ef20395ed050bf7ce26fe0dd +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466020430cef83f07cba7613bcc24dd903e5ade856baf212f0f228c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f67e4c95336d43f8f72939e99f678331124ae5f5d9bd5e40a41ddded5a0a1b12a912e09376977a94197b3cc225e0e569eadb761ca33e775aea82d000ceefd76c3ff19449df3a1af2f503 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5b12ab52b1ee79a1114c3407e153f320863dfc86a0d98764f62651c50e2ede +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c5f2aed3a22d04a2107aca55f25a31366bc246ed6b52d3e71a413409d3e1ce + +handshake=Noise_XKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625429519d9da85dd8bb5090f9c0bc4acb54b3ba8a24ec56fa5f4ba0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f4d74c505f803c54065e454d0a3bdf2ef4a40b24693c281ae2a +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=0bb72e926efbf321955a792b7ccb45a295c6d5f031f59648c9662b709a8df5072540b38091cd1530656d7015185d682f3ceb21a2f48b1ad5b7f4094a2660dedd7fafa40dc6febe793f19 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=974c226eca2032beaa7dc8e9ee1ac58e566cb305fbc79cca8ffa77eb6a02d0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94e1425470776282f7e9751698cc7ba2ae5dc0cb3c8d9b189021f6b94e65ec + +handshake=Noise_XKpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a6f963df7b04718a9a3a3e16e953cef0de71cf553539d8859d24 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a13bb0d71fd337f74bd528c12f0b90fde211edca976ede0a3292 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c1a1778bfba62342d38b2dc7c5042d7e809efc74a6d780d2d7589673e27a3a1a5fdd43d30c8689a043ef99c917b9f36308eab30f236b34955872cb86d6b3e197c9e019fc833ba40868a2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f4b75252b4249d95ebbc815bee87953b2bc4d6bc1ca89237d9196ab363b7fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f0a47d13ace24e87f0b5319eea0bc141a410d4d1ae2705e4a0dc5fd168c867 + +handshake=Noise_IK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419d6fab175300a577115c701c41ed681373f0432f81d3bf8676bd05216cd1919ba2eaa418fdd8e09ae59d7cf57869de42789c3b9ca915c2cacf009f9d0e4436e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846623c019a124da3f096e964fe624cf65db +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=80a75e75c8e8d2e9c2a6c7bc6e550c4997d6d2b45429a530821c4aa5d36f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b8475410da62a98493d33a1e669f8f56dd8f61d449b53bd375299c3435424a + +handshake=Noise_IKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254694ead724bb690ad27ce3893ebd8394b455e44e362122cce141b66200c2ac5a3db8bb908bbf1254f7f74801e5058e5e819dd00881b21a04144c1824606c0c078 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dc8096770cbc501e31c8d2275ea75642 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2471b2688160616fc0bd108fde1be5848e763d448a018f8f9052697444a95a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e48f8d2d66ccb8f59321228086764d403dac49de50617604bd4e1399ec7714 + +handshake=Noise_IKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d090a76917ed86b1ca3f8af8ac5c0803d5b3b290ab95fa415d8bf2f9200a59fc34c54450e0a71f213dbb91f5a5843c28a1b1e94ea7a8c729788b074f894477f7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846635c80f45db0193be6c76fa63c43b2230 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=245e2f9694b825a856dc97709fcc450870d23dd07637b57d21268ad60016e4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=977eb8234bef8ece7a14c771fa5019aae42c0f4655d4e1ffbfdb4a96def193 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540322be5210eec7e84567f5b4ad376b908b7c38a587eb71776e0661a6ca9f3ef251962835db06e694781bcf163d3cb38dfe6ffdada1fcf40492123fd5eae6c0c9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f9d3c922ccf0a76efc90a08b4d23df61 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c033f4a3312af700a5a655f6992bcad095ceb5af11b02027cecd87ef65738c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3363987af8578ae96cb358858a859ef8060129a05d85700d8a9c4955c599c1 + +handshake=Noise_IK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419d6fab175300a577115c701c41ed681373f0432f81d3bf8676bd05216cd1919ba2eaa418fdd8e09ae59d7cf57869de4e6d8177aa9777fe9b843100e255aee76034f61b96b52af38660c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846658a7bb8caac509783390e5a04df4a3ca570b2bcdf65f8c1c40cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=80a75e75c8e8d2e9c2a6c7bc6e550c4997d6d2b45429a530821c4aa5d36f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b8475410da62a98493d33a1e669f8f56dd8f61d449b53bd375299c3435424a + +handshake=Noise_IKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254694ead724bb690ad27ce3893ebd8394b455e44e362122cce141b66200c2ac5a3db8bb908bbf1254f7f74801e5058e5e817106241219f60be8d1a7770f3def3c59038d187a53c0362f190 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6bef292d60d7dd4c6d157f33e863b7b6d53ba0113ae21d8deea +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2471b2688160616fc0bd108fde1be5848e763d448a018f8f9052697444a95a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e48f8d2d66ccb8f59321228086764d403dac49de50617604bd4e1399ec7714 + +handshake=Noise_IKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d090a76917ed86b1ca3f8af8ac5c0803d5b3b290ab95fa415d8bf2f9200a59fc34c54450e0a71f213dbb91f5a5843c28720b9cbc2e1f0e39ae53c6fe9b31a70aa73d77909aafd3d3c36b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c92aa230bccd4126f41b8aa35f2c0e1b7d53e57df197dc13feb7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=245e2f9694b825a856dc97709fcc450870d23dd07637b57d21268ad60016e4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=977eb8234bef8ece7a14c771fa5019aae42c0f4655d4e1ffbfdb4a96def193 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540322be5210eec7e84567f5b4ad376b908b7c38a587eb71776e0661a6ca9f3ef251962835db06e694781bcf163d3cb38d2dbe7ee0a408573e5466e702c802dce4b432bd175dff1a5caae4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466574ad0a465f5fa10665727be848a181ffd21211d5aa7d5be8e28 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c033f4a3312af700a5a655f6992bcad095ceb5af11b02027cecd87ef65738c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3363987af8578ae96cb358858a859ef8060129a05d85700d8a9c4955c599c1 + +handshake=Noise_IK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419d6fab175300a577115c701c41ed681373f0432f81d3bf8676bd05216cd1919e61b75ccef0c0cf0b216fcdf371d0859ab50373f8c7b70a239f8cc8318e6075b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb50a12b50b0b1b43fc6725181315302 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=80a75e75c8e8d2e9c2a6c7bc6e550c4997d6d2b45429a530821c4aa5d36f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b8475410da62a98493d33a1e669f8f56dd8f61d449b53bd375299c3435424a + +handshake=Noise_IKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254694ead724bb690ad27ce3893ebd8394b455e44e362122cce141b66200c2ac5a340048ce6c8456ff4837c29fe67256f81c751b0c269239a167fbf0300dfb648a3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666d2b48b1cea39effcb0d05417086092 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2471b2688160616fc0bd108fde1be5848e763d448a018f8f9052697444a95a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e48f8d2d66ccb8f59321228086764d403dac49de50617604bd4e1399ec7714 + +handshake=Noise_IKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d090a76917ed86b1ca3f8af8ac5c0803d5b3b290ab95fa415d8bf2f9200a59fc0aef8b6d695b38b638d8a84ff6029bfa1389fc6a2c64763e1546d48733e7a69f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846681140ff7535a34e76cec240241c16675 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=245e2f9694b825a856dc97709fcc450870d23dd07637b57d21268ad60016e4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=977eb8234bef8ece7a14c771fa5019aae42c0f4655d4e1ffbfdb4a96def193 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540322be5210eec7e84567f5b4ad376b908b7c38a587eb71776e0661a6ca9f3ef2da7e079ebdd84739c3bce2764827999b754f95e803096d0591567119765f495e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466848adcd10e9bc9826df50f4b6bc66b29 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c033f4a3312af700a5a655f6992bcad095ceb5af11b02027cecd87ef65738c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3363987af8578ae96cb358858a859ef8060129a05d85700d8a9c4955c599c1 + +handshake=Noise_IK_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419d6fab175300a577115c701c41ed681373f0432f81d3bf8676bd05216cd1919e61b75ccef0c0cf0b216fcdf371d0859e6d8177aa9777fe9b8435bb6f8202c3acd9051a9aee0a63e76f6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846658a7bb8caac5097833909e90778571d34ce0e5b6ea4c3a76f102 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=80a75e75c8e8d2e9c2a6c7bc6e550c4997d6d2b45429a530821c4aa5d36f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b8475410da62a98493d33a1e669f8f56dd8f61d449b53bd375299c3435424a + +handshake=Noise_IKpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254694ead724bb690ad27ce3893ebd8394b455e44e362122cce141b66200c2ac5a340048ce6c8456ff4837c29fe67256f8117106241219f60be8d1ad5cce3624dd12b08c8095b0abfe558a2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6bef292d60d7dd4c6d103923a164717d1f2c43d4a0be832d29f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2471b2688160616fc0bd108fde1be5848e763d448a018f8f9052697444a95a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e48f8d2d66ccb8f59321228086764d403dac49de50617604bd4e1399ec7714 + +handshake=Noise_IKpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d090a76917ed86b1ca3f8af8ac5c0803d5b3b290ab95fa415d8bf2f9200a59fc0aef8b6d695b38b638d8a84ff6029bfa720b9cbc2e1f0e39ae53481de7823a9ec40e8e82d4e52bdbe833 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c92aa230bccd4126f41bba00c0183e8a92b2d41d3874e2d39c67 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=245e2f9694b825a856dc97709fcc450870d23dd07637b57d21268ad60016e4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=977eb8234bef8ece7a14c771fa5019aae42c0f4655d4e1ffbfdb4a96def193 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540322be5210eec7e84567f5b4ad376b908b7c38a587eb71776e0661a6ca9f3ef2da7e079ebdd84739c3bce2764827999b2dbe7ee0a408573e5466b25ab358115f0cafc7c888119dfb98cc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466574ad0a465f5fa106657b9f7927e737f39dbed9fe3bf511849f9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c033f4a3312af700a5a655f6992bcad095ceb5af11b02027cecd87ef65738c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3363987af8578ae96cb358858a859ef8060129a05d85700d8a9c4955c599c1 + +handshake=Noise_XX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665393019dbd6f438795da206db0886610b26108e424142c2e9b5fd1f7ea70cde8767ce62d7e3c0e9bcefe4ab872c0505b9e824df091b74ffe10a2b32809cab21f +msg_2_payload= +msg_2_ciphertext=e610eadc4b00c17708bf223f29a66f02342fbedf6c0044736544b9271821ae40e70144cecd9d265dffdc5bb8e051c3f83db32a425e04d8f510c58a43325fbc56 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9ea1da1ec3bfecfffab213e537ed1791bfa887dd9c631351b3f63d6315ab9a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=217c5111fad7afde33bd28abaff3def88a57ab50515115d23a10f28621f842 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f10774870f2c18bd60e3a1629fee0e9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466807dca8877a33959186ac0181ac963a7dd13a134ae4a2191da2bedd96911f7b1f2d8f840385aff491d71970b02691ec2ab2beffd1b374db8c8f15cabcb3fddf5 +msg_2_payload= +msg_2_ciphertext=099fd29f5cad05f9d2c9be076d04e80a092e181fa13a4e844386e360defdca4ea1c15be27443d30d40db0e319f9e614f40a41d90532d7a3684ebc440d9bb73eb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=99521768e8b75eae6d56db072601817fd0606206ca444b02f911562521e4fd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ab15274dff9f222379cd9feac0e4a82b7fb61fc0c79372dd9c07d283b1e765 + +handshake=Noise_XXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b6dcbceafe33638fea90c80dd1e8d203 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667017a62eaf03e7998188e6751f9fcac8bc79848fad62102c1936a2af6aef691c0d9fd04c9fe5018b678e0a6d7333ffaa5860ab1d5bc128e25eff7403eaa53864 +msg_2_payload= +msg_2_ciphertext=8f83154157fddfe88c38ce42a13b74127986fd61dc310450deb5ff6a181fa057639b6fba5e0842781640b7b7c5cf8bdf19ee4436359d40f4214c59aaa2971736 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=776c311a7a1a1a31a0fa9950b6435a8116fc986c30aefb84b1de1a1ea3e0cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c79820d7cd308ba3da226008598c022aeb8f084dde84fee307293a3634e331 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544cff7d0c96d894314bd03f327cbac98f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc9f39c99cf603e2db23dbe9ce2adec44a572047d4a1d3f8c0df894e11f5bd7fa2fdaa0856557bcc2c4276a81ce70f63fa33069acf2dc7b13f505aa0cfda1372 +msg_2_payload= +msg_2_ciphertext=b58fc4f341feab3fe253ee6489ad653afe49fcc6eea1f18a892b1a8febc146eed9bacb291dfc7a05015e8a9ff6c4aea6f5090a8fe040a0628bf348f670144762 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fc4829fa5f449a9aca1577156e58691997a90a5a55b7aa6401257535595eb9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b069da251403dba1f073a2fea640f5a8cc91d1f012a01c1fa87435a8492030 + +handshake=Noise_XXpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e3443cc5cde4af71a33c6b56cbc00ea8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb1259f77345353d70dcef1e97d161dd9c3324e72b46203ebe87dcb40159eb6683aae01b5e9a0d3b45f0cc22a1eba217aa52f541c089a733541cbace7919e264 +msg_2_payload= +msg_2_ciphertext=a702c30239110afbb8afacb639f961e5c2574c3fe59ee6069c0f5f5414ea249379e58f0d514bb0f277ffe5ae6e6aecf9f4c58681a8586ac9878e6b9a086f4e40 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=187cadad4158250d0af49c2aea3bedc34aee2cc962336fbe649527ca78e48c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=91de652b73884e25506003fe72969748b9092a4518be9c6e4911a52b60375f + +handshake=Noise_XX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665393019dbd6f438795da206db0886610b26108e424142c2e9b5fd1f7ea70cde8c9f29dcec8d3ab554f4a5330657867fe4917917195c8cf360e08d6dc5f71baf875ec6e3bfc7afda4c9c2 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e610eadc4b00c17708bf223f29a66f02342fbedf6c0044736544b9271821ae40232c55cd96d1350af861f6a04978f7d5e070c07602c6b84d25a331242a71c50ae31dd4c164267fd48bd2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9ea1da1ec3bfecfffab213e537ed1791bfa887dd9c631351b3f63d6315ab9a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=217c5111fad7afde33bd28abaff3def88a57ab50515115d23a10f28621f842 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542dfece4dae76dc5ac85cb897862e0637e7403c75bb5761111b83 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466807dca8877a33959186ac0181ac963a7dd13a134ae4a2191da2bedd96911f7b1549721eaf8b8212a701886c355be87e686ae9e443b823f0d58eceab3e52ff4d365f9b6793b5a6e913e82 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=099fd29f5cad05f9d2c9be076d04e80a092e181fa13a4e844386e360defdca4e476fccf79130a33fd25244336598bf55637ea8dea2acb6fd2e6c98213519f6f2d25947620be6979e3858 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=99521768e8b75eae6d56db072601817fd0606206ca444b02f911562521e4fd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ab15274dff9f222379cd9feac0e4a82b7fb61fc0c79372dd9c07d283b1e765 + +handshake=Noise_XXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b1c5b18c538c8c63ca5d317942e39790c9a490ec0349924c9f1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667017a62eaf03e7998188e6751f9fcac8bc79848fad62102c1936a2af6aef691c0ad62dc8498b97040b8a96630d1c68a6f8fbe4180e999511b4e3bfa3e0ae626aa97e13adc6eeaa2d4310 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8f83154157fddfe88c38ce42a13b74127986fd61dc310450deb5ff6a181fa057acf4829f9429fc717589b9998148cf0580a72833458eaac993ba86ca4314f11ac370f7fb7a1d92360504 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=776c311a7a1a1a31a0fa9950b6435a8116fc986c30aefb84b1de1a1ea3e0cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c79820d7cd308ba3da226008598c022aeb8f084dde84fee307293a3634e331 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625444c72fdfcc26b692b2435ad02e6c7f0c07226d2edd62204fbe9c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc9f39c99cf603e2db23dbe9ce2adec44a572047d4a1d3f8c0df894e11f5bd7f45cdfbefb68a646406aebe4c1987a2686d93f50fbd193f60379e3691036e92cb41993381816ab66d1ea3 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b58fc4f341feab3fe253ee6489ad653afe49fcc6eea1f18a892b1a8febc146ee526267e460783c68aefd8a71354f3919ae4d3c4c228a97bbbbef8021883cd1832050c4b17c7b02155569 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fc4829fa5f449a9aca1577156e58691997a90a5a55b7aa6401257535595eb9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b069da251403dba1f073a2fea640f5a8cc91d1f012a01c1fa87435a8492030 + +handshake=Noise_XXpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545d791aebd7b1ff3a73ba5c27944833f62facffa3b38f7ec45f9f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb1259f77345353d70dcef1e97d161dd9c3324e72b46203ebe87dcb40159eb66954fa813c5770391ff0e4006fa005462b1bfa8057f6e8f62584a272b0eec13b6cf6a75a736ddf5d0d3cd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a702c30239110afbb8afacb639f961e5c2574c3fe59ee6069c0f5f5414ea2493ab8dbfb3e1f6148b9c0d93e8d9ebf5183e3be30d1cb36cf2cd66eccebe0493ead2ba5f2bfae0d821ce21 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=187cadad4158250d0af49c2aea3bedc34aee2cc962336fbe649527ca78e48c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=91de652b73884e25506003fe72969748b9092a4518be9c6e4911a52b60375f + +handshake=Noise_XX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665393019dbd6f438795da206db0886610b26108e424142c2e9b5fd1f7ea70cde8545f22cc3b52e6cf83a9266ed4850a7a3460f29794110cc1e4c4b5241c939f90 +msg_2_payload= +msg_2_ciphertext=e610eadc4b00c17708bf223f29a66f02342fbedf6c0044736544b9271821ae406561124920ea641646ea97786397ad23ab2f0dbf49fc3e46328b481b0924438c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9ea1da1ec3bfecfffab213e537ed1791bfa887dd9c631351b3f63d6315ab9a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=217c5111fad7afde33bd28abaff3def88a57ab50515115d23a10f28621f842 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fbf84632d6f2ee3f0f542ed012795e4a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466807dca8877a33959186ac0181ac963a7dd13a134ae4a2191da2bedd96911f7b1aaf8f55fffe1c50fc9ee9c46feba7bf8b04117ac48bc436c3818f5ec5ee45db1 +msg_2_payload= +msg_2_ciphertext=099fd29f5cad05f9d2c9be076d04e80a092e181fa13a4e844386e360defdca4e9b9f67a4e8a1de4333f67defea7fd8f4e39466651c8681fea507cfa7f3bfe155 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=99521768e8b75eae6d56db072601817fd0606206ca444b02f911562521e4fd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ab15274dff9f222379cd9feac0e4a82b7fb61fc0c79372dd9c07d283b1e765 + +handshake=Noise_XXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254709a9d93b489223c7fa509f35c2c19af +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667017a62eaf03e7998188e6751f9fcac8bc79848fad62102c1936a2af6aef691c503cbdb4cdc7d576fc13f89c8322308ebed27aa285cc83ac65c8ba19224c22a7 +msg_2_payload= +msg_2_ciphertext=8f83154157fddfe88c38ce42a13b74127986fd61dc310450deb5ff6a181fa0574ab7d599dfa195ed182e163ebd919f8648105379593b3f75dc78fd0dd274bbec +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=776c311a7a1a1a31a0fa9950b6435a8116fc986c30aefb84b1de1a1ea3e0cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c79820d7cd308ba3da226008598c022aeb8f084dde84fee307293a3634e331 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bdfc6a80d9f928922f8dd436a4005e3c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc9f39c99cf603e2db23dbe9ce2adec44a572047d4a1d3f8c0df894e11f5bd7f29af04d33962ddd8a7c6a4c775f29008ef90fbab2ec1b7782668304fcd060294 +msg_2_payload= +msg_2_ciphertext=b58fc4f341feab3fe253ee6489ad653afe49fcc6eea1f18a892b1a8febc146ee0decb17e6bf529ac042e8ec4b2226614d28c6c9477b1f2d0bdbee3b53eaaac81 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fc4829fa5f449a9aca1577156e58691997a90a5a55b7aa6401257535595eb9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b069da251403dba1f073a2fea640f5a8cc91d1f012a01c1fa87435a8492030 + +handshake=Noise_XXpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b2f4adfa73e9ba5320d7dad00152ab9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb1259f77345353d70dcef1e97d161dd9c3324e72b46203ebe87dcb40159eb666198ef90bf6d0b1a0e76374ae604ac12c54156a8210758dea8c50d8720b4533f +msg_2_payload= +msg_2_ciphertext=a702c30239110afbb8afacb639f961e5c2574c3fe59ee6069c0f5f5414ea2493bf47ccd868daf2dc792d2a6493790f4a804d0508de91173260899064d056c042 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=187cadad4158250d0af49c2aea3bedc34aee2cc962336fbe649527ca78e48c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=91de652b73884e25506003fe72969748b9092a4518be9c6e4911a52b60375f + +handshake=Noise_XX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665393019dbd6f438795da206db0886610b26108e424142c2e9b5fd1f7ea70cde847f6866f15c3cd3f864f7ed682f1711a4917917195c8cf360e080035dfa88af5c6e9b820278e6016f7d7 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e610eadc4b00c17708bf223f29a66f02342fbedf6c0044736544b9271821ae403bbe475185a4a265a50e1d43bdaeee7fe070c07602c6b84d25a3b4064af5be30115a052069038f5002a3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9ea1da1ec3bfecfffab213e537ed1791bfa887dd9c631351b3f63d6315ab9a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=217c5111fad7afde33bd28abaff3def88a57ab50515115d23a10f28621f842 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542dfece4dae76dc5ac85c1825d578f5381e8a6ca0ff8b782f9c86 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466807dca8877a33959186ac0181ac963a7dd13a134ae4a2191da2bedd96911f7b103f1588855356691eb8e399bd3cfd5f486ae9e443b823f0d58ec04fb2ea6275da3194a478e2d24af9a23 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=099fd29f5cad05f9d2c9be076d04e80a092e181fa13a4e844386e360defdca4e8223254ae6ec8e2f94404c1b2cfbf633637ea8dea2acb6fd2e6cf013d5bcd43885c658750a9d5af5c7ec +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=99521768e8b75eae6d56db072601817fd0606206ca444b02f911562521e4fd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ab15274dff9f222379cd9feac0e4a82b7fb61fc0c79372dd9c07d283b1e765 + +handshake=Noise_XXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b1c5b18c538c8c63ca5dd70a54c15168915bf5edbab2df12bf2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667017a62eaf03e7998188e6751f9fcac8bc79848fad62102c1936a2af6aef691c29dfd353ee7b2c1ac5031544aa7e2814f8fbe4180e999511b4e32e3fa0a009cdc7b9c20ce6b5787f9fcf +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8f83154157fddfe88c38ce42a13b74127986fd61dc310450deb5ff6a181fa057d96927eaac505ff481efa6f1c092dd1880a72833458eaac993ba5e19641750e4f2195fa3af7b5f369a1a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=776c311a7a1a1a31a0fa9950b6435a8116fc986c30aefb84b1de1a1ea3e0cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c79820d7cd308ba3da226008598c022aeb8f084dde84fee307293a3634e331 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625444c72fdfcc26b692b243fd1e0d69cd5735b9af404ae7ddc7f15e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc9f39c99cf603e2db23dbe9ce2adec44a572047d4a1d3f8c0df894e11f5bd7f9ed5a62a0d63ccfc5b60d1420eb1d4ac6d93f50fbd193f60379e2140cdb6860d1460b007be5c8064da95 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b58fc4f341feab3fe253ee6489ad653afe49fcc6eea1f18a892b1a8febc146ee309032b5b433c34b4982844c2cc0e449ae4d3c4c228a97bbbbef52a9e44f4a52de079ba231a6b68a45c9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fc4829fa5f449a9aca1577156e58691997a90a5a55b7aa6401257535595eb9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b069da251403dba1f073a2fea640f5a8cc91d1f012a01c1fa87435a8492030 + +handshake=Noise_XXpsk3_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545d791aebd7b1ff3a73ba67c693699d548895df3e86b1204b11fe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb1259f77345353d70dcef1e97d161dd9c3324e72b46203ebe87dcb40159eb6603c900a563c48b22719b49f31437cfe9b1bfa8057f6e8f62584a5a0257c9eede97ecbafd2890e6551923 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a702c30239110afbb8afacb639f961e5c2574c3fe59ee6069c0f5f5414ea2493462db30239ac36a9b70292f81f30fb9d3e3be30d1cb36cf2cd66b2c4bb6a84a19a1a06ab7ba66b78b51d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=187cadad4158250d0af49c2aea3bedc34aee2cc962336fbe649527ca78e48c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=91de652b73884e25506003fe72969748b9092a4518be9c6e4911a52b60375f + +handshake=Noise_IX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dafa2f50bec421c6e061a97013b8d9d582911be531e7e463f108e9389c74d589e2173945cfe456788f1608bdbf6a9c2b34c089108e662e613ac961e8dbc9973b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=40c12ccfdf59f44d7cfc8c7dfe8a1bf739107c31aebcfc9f4caee7dc9099c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c3beff2f2144bb23f7fae6fd03578c40f1ef01140d1721a9e895958d52d749 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a91f197ee337c37f7558ccd2074c61fa06784cb2e6325bde19d184ae68e6e2f7c5fbaa3a25628896bcd7c942ae437a7a87c84b7586565643e6ee0655cda423d7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661b13bcef5c9664ec91e1fe0a4cc3e93850404c874f059b5f5b83d938d3f52f3e20d6a62ed81ee66161a8c14b2863f63ca88e762840a3c3700c6b382593438f14 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=55e01923ed15f82aaf69393cd6b0d110fd22ba39dcf8207e5c8fb4195a70b2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5f5e31e3d5052cfc8537d909b3a5fcc1ccb0cab5d18d251ebeef84a4b1291e + +handshake=Noise_IXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541e878f7607084d4358e3208e796d5ee88ad8308f9923074721451e423633bc5d1e769a44d8f7165f9ea0fd7975979d4fdbeff3a05fc29dddb9a32a6f56f3a181 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e0bb8499ca20b384a845a39c290e882f1265f343e60402d87f7f0a692cef64aed150f315e4e68d26f4660e3466e88ee0495de1450357491205f38deb68cc300 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5d4fce475e4aecd6ab801c48e89b67c13944bfa41cfc1626fafdf6cec81ca3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed29ef74538577291ee8371eaca37b99b83075b1bb24f983424bb7a25c9c86 + +handshake=Noise_IXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625459d797d678b29e8942571b69bc6342f0db2a1e4ec05bbfb2463649f5975c40086e1ad80e495a50a4f4542fe96b7616dce2a7cc1f2e96e85edceb2682deb0dac0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466745c5b31c6f91c0cc8c3ae7c831e8bb738ef935be56395d0873b630272c030e86d6c4411d18d8fbcf7778e8d4ca089246f78101a9d83e153aab291dfaca58c94 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d3ac1bd570b82aabc14ba11621d5fd435b751272ebe757406ff922de938d5c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a198c97f2c167512d40ab32fbb13c9e32ae975836561a5829ba67500cbb6da + +handshake=Noise_IX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dafa2f50bec421c6e061a97013b8d9d582911be531e7e463f108e9389c74d589194a720639279eaac9d876aa00c2ece2e8761a2ca307ad49797cd0cea8728f2de0b353ea74d3206276e7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=40c12ccfdf59f44d7cfc8c7dfe8a1bf739107c31aebcfc9f4caee7dc9099c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c3beff2f2144bb23f7fae6fd03578c40f1ef01140d1721a9e895958d52d749 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a91f197ee337c37f7558ccd2074c61fa06784cb2e6325bde19d184ae68e6e2f7c5fbaa3a25628896bcd7c942ae437a7aaf6d3b1fcdb3d8b4b960dfb37a0ba15ad240169da3792d74764f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661b13bcef5c9664ec91e1fe0a4cc3e93850404c874f059b5f5b83d938d3f52f3ea6c0faf70b81e4686242650bcbb0c110a9cac6dcfc56cd3154b1e658fe0219a8b54d08d5d6e41d78d2b2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=55e01923ed15f82aaf69393cd6b0d110fd22ba39dcf8207e5c8fb4195a70b2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5f5e31e3d5052cfc8537d909b3a5fcc1ccb0cab5d18d251ebeef84a4b1291e + +handshake=Noise_IXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541e878f7607084d4358e3208e796d5ee88ad8308f9923074721451e423633bc5d1e769a44d8f7165f9ea0fd7975979d4fc0e1d27b58cf97cb222256a1edd2ab44b910c8140d4e2b4690e0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e0bb8499ca20b384a845a39c290e882f1265f343e60402d87f7f0a692cef64a66496d0efa8152e6bfe8a2a2f01c2372ffce0d6e6c24e5933f5c8ef7a18d167e99f292e70e7d023e5d58 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5d4fce475e4aecd6ab801c48e89b67c13944bfa41cfc1626fafdf6cec81ca3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed29ef74538577291ee8371eaca37b99b83075b1bb24f983424bb7a25c9c86 + +handshake=Noise_IXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625459d797d678b29e8942571b69bc6342f0db2a1e4ec05bbfb2463649f5975c40086e1ad80e495a50a4f4542fe96b7616dc9416d6c2f17c1f823e517767c4777936ee38c25aa7909362a631 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466745c5b31c6f91c0cc8c3ae7c831e8bb738ef935be56395d0873b630272c030e82a6e818375056d17651f621b08a6ca2f3a9706957d7bf986e2612cbb0ea0f3bcf6bc5f2120a9335a4c17 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d3ac1bd570b82aabc14ba11621d5fd435b751272ebe757406ff922de938d5c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a198c97f2c167512d40ab32fbb13c9e32ae975836561a5829ba67500cbb6da + +handshake=Noise_IX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dafa2f50bec421c6e061a97013b8d9d582911be531e7e463f108e9389c74d589086054f914b582ee1157d334cc2285b0040b4468e33e04ac80cb099169d516d8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=40c12ccfdf59f44d7cfc8c7dfe8a1bf739107c31aebcfc9f4caee7dc9099c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c3beff2f2144bb23f7fae6fd03578c40f1ef01140d1721a9e895958d52d749 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a91f197ee337c37f7558ccd2074c61fa06784cb2e6325bde19d184ae68e6e2f7127226d6423aee99c69f7fe7f1519f7bdef89bc28f30e4d31bd0144c659a67f8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661b13bcef5c9664ec91e1fe0a4cc3e93850404c874f059b5f5b83d938d3f52f3e3d7958a73d23d96ff791d7a09dd76b4faf040e5aae642241824179c0d8283d12 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=55e01923ed15f82aaf69393cd6b0d110fd22ba39dcf8207e5c8fb4195a70b2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5f5e31e3d5052cfc8537d909b3a5fcc1ccb0cab5d18d251ebeef84a4b1291e + +handshake=Noise_IXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541e878f7607084d4358e3208e796d5ee88ad8308f9923074721451e423633bc5d36dc199e0216a43e03de5bf3c64456a06356b5f1cccee247341e7139c92f79c6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e0bb8499ca20b384a845a39c290e882f1265f343e60402d87f7f0a692cef64af697b08e044030d3090eaaed4751659063846cc79067c9c33723a8becb43f6cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5d4fce475e4aecd6ab801c48e89b67c13944bfa41cfc1626fafdf6cec81ca3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed29ef74538577291ee8371eaca37b99b83075b1bb24f983424bb7a25c9c86 + +handshake=Noise_IXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625459d797d678b29e8942571b69bc6342f0db2a1e4ec05bbfb2463649f5975c4008bca99e5fe64bd7f59f9c37a10403d8d14b1615d40596696d4e6c3b32a55fbf4b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466745c5b31c6f91c0cc8c3ae7c831e8bb738ef935be56395d0873b630272c030e85aa03f2d4d61e222a2ebdef29b4652d1dbabae33699f4f0aac9ad1000e5d5e58 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d3ac1bd570b82aabc14ba11621d5fd435b751272ebe757406ff922de938d5c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a198c97f2c167512d40ab32fbb13c9e32ae975836561a5829ba67500cbb6da + +handshake=Noise_IX_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dafa2f50bec421c6e061a97013b8d9d582911be531e7e463f108e9389c74d58943c11157db485d61bcaa6d51bcd3251fe8761a2ca307ad49797cecb71b657aee8eec2c351eb5368ef14f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=40c12ccfdf59f44d7cfc8c7dfe8a1bf739107c31aebcfc9f4caee7dc9099c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c3beff2f2144bb23f7fae6fd03578c40f1ef01140d1721a9e895958d52d749 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a91f197ee337c37f7558ccd2074c61fa06784cb2e6325bde19d184ae68e6e2f7127226d6423aee99c69f7fe7f1519f7baf6d3b1fcdb3d8b4b9600be4f2dfc45f94e73292417c3764424e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661b13bcef5c9664ec91e1fe0a4cc3e93850404c874f059b5f5b83d938d3f52f3ea278af51752e31746b5e7a8e38fbfb4aa9cac6dcfc56cd3154b18cb5958a8adfbab8090a26084474ccc9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=55e01923ed15f82aaf69393cd6b0d110fd22ba39dcf8207e5c8fb4195a70b2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5f5e31e3d5052cfc8537d909b3a5fcc1ccb0cab5d18d251ebeef84a4b1291e + +handshake=Noise_IXpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541e878f7607084d4358e3208e796d5ee88ad8308f9923074721451e423633bc5d36dc199e0216a43e03de5bf3c64456a0c0e1d27b58cf97cb2222ca38d777b3404140852ac27381a72b65 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e0bb8499ca20b384a845a39c290e882f1265f343e60402d87f7f0a692cef64aefb82f6c91194d02d31b7e243b5266deffce0d6e6c24e5933f5c1055c6cd239df4ac4a2b751ac57172a6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5d4fce475e4aecd6ab801c48e89b67c13944bfa41cfc1626fafdf6cec81ca3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed29ef74538577291ee8371eaca37b99b83075b1bb24f983424bb7a25c9c86 + +handshake=Noise_IXpsk2_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625459d797d678b29e8942571b69bc6342f0db2a1e4ec05bbfb2463649f5975c4008bca99e5fe64bd7f59f9c37a10403d8d19416d6c2f17c1f823e51ea085f223d835b5cdb3dbbc997748dd0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466745c5b31c6f91c0cc8c3ae7c831e8bb738ef935be56395d0873b630272c030e8112d7dfed0b36fbd90f66a4865905ff13a9706957d7bf986e2615ddc0e1023ec5831d8b1c3a6bca38ee6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d3ac1bd570b82aabc14ba11621d5fd435b751272ebe757406ff922de938d5c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a198c97f2c167512d40ab32fbb13c9e32ae975836561a5829ba67500cbb6da + +handshake=Noise_N_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471bcc2ec91fac5d2551b8a08e39ae5ab +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=374a734846ea8b76251255d17bae5b5313087ff42afa23ed42a5b5bf325804 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=922037b8012e37d18adb6827375085f06f034888ea3f625dfc91d424334290 + +handshake=Noise_Npsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254340a10ebcc2642dfbcf5af7f2bf975a9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e20e59bdd4cb2aa25691345a5b462b2cf85084b15643091c4fc173f16dc5d7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=68c7d8986c79c6f8b4589765ef1cc903024c6e8759bf05776335d9e065abe7 + +handshake=Noise_Npsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bd29db2d71093718be3c9068ae19b028 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=3caf03e7b531dd629d062fa119ea14d08939bf79327005f276b9a99c5400f0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4638116fe8341f36f69c2e646687fd4f6b5b5f10dec581a9ca8202f016f8f8 + +handshake=Noise_N_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df115f83f13b64589fecddf876dd30eb9ba694948e5169479513 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=374a734846ea8b76251255d17bae5b5313087ff42afa23ed42a5b5bf325804 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=922037b8012e37d18adb6827375085f06f034888ea3f625dfc91d424334290 + +handshake=Noise_Npsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625406dd68c4f13f48b25468230d7cef980524e27eaabc8ba348da29 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e20e59bdd4cb2aa25691345a5b462b2cf85084b15643091c4fc173f16dc5d7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=68c7d8986c79c6f8b4589765ef1cc903024c6e8759bf05776335d9e065abe7 + +handshake=Noise_Npsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c13a66d1ae511893d991fdd6649d5aa540467596b854ff69e59e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=3caf03e7b531dd629d062fa119ea14d08939bf79327005f276b9a99c5400f0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4638116fe8341f36f69c2e646687fd4f6b5b5f10dec581a9ca8202f016f8f8 + +handshake=Noise_N_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ceb26e62698f0a9d16577f5fcb929fb3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=374a734846ea8b76251255d17bae5b5313087ff42afa23ed42a5b5bf325804 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=922037b8012e37d18adb6827375085f06f034888ea3f625dfc91d424334290 + +handshake=Noise_Npsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c84f374576798a9ac7c4e4f3d6fb1660 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e20e59bdd4cb2aa25691345a5b462b2cf85084b15643091c4fc173f16dc5d7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=68c7d8986c79c6f8b4589765ef1cc903024c6e8759bf05776335d9e065abe7 + +handshake=Noise_Npsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b20f16a10cf8aec5558e9615c798606 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=3caf03e7b531dd629d062fa119ea14d08939bf79327005f276b9a99c5400f0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4638116fe8341f36f69c2e646687fd4f6b5b5f10dec581a9ca8202f016f8f8 + +handshake=Noise_N_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df115f83f13b64589fec852ae179184185e9d29fed35f4d235dc +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=374a734846ea8b76251255d17bae5b5313087ff42afa23ed42a5b5bf325804 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=922037b8012e37d18adb6827375085f06f034888ea3f625dfc91d424334290 + +handshake=Noise_Npsk0_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625406dd68c4f13f48b25468727d65e4f2c438542b1a8181a53dcc73 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e20e59bdd4cb2aa25691345a5b462b2cf85084b15643091c4fc173f16dc5d7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=68c7d8986c79c6f8b4589765ef1cc903024c6e8759bf05776335d9e065abe7 + +handshake=Noise_Npsk1_25519_AESGCM_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c13a66d1ae511893d9916e916af9cabdd72bf1d4e58c91685c96 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=3caf03e7b531dd629d062fa119ea14d08939bf79327005f276b9a99c5400f0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4638116fe8341f36f69c2e646687fd4f6b5b5f10dec581a9ca8202f016f8f8 + +handshake=Noise_K_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cc4041bbf40e26aea2c61f36b29dfda1 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=aca1ae00ed718c11ae8f91c3c289db54dca4fba284098248984158f4afb15a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=334cde4d2b9e7189be333e05c4e8ca8cbe9a7e9e3170dc61abf51906f95f9b + +handshake=Noise_Kpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6463591c0d8b8fd209cf3c80579bfed +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7736979bc1fc8d5c7d42c92ea41ee59e97d59faafe791a2e3d58c8e8fb9929 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03236fadebc8f6a18ecb878d1ac2b78a3cf0e0024d0fb5d8b9d105ea194980 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254443d03b8955d57e4fcbdf961645c0db9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1429bc785fdc4adc51006b72f574c963bc97309e22feb0b54f8b944292af3b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c74d5a471091962d858c65542df842172e2e95a85bfe0eea2c6be86c8bfd89 + +handshake=Noise_K_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625428f2b400a063dbdce02b182da650e11fdf8ee63bffbdb9263e2d +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=aca1ae00ed718c11ae8f91c3c289db54dca4fba284098248984158f4afb15a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=334cde4d2b9e7189be333e05c4e8ca8cbe9a7e9e3170dc61abf51906f95f9b + +handshake=Noise_Kpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c2b61d59cbbc7e45c9743b816be7edfacba1a21c0b4ea6499687 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7736979bc1fc8d5c7d42c92ea41ee59e97d59faafe791a2e3d58c8e8fb9929 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03236fadebc8f6a18ecb878d1ac2b78a3cf0e0024d0fb5d8b9d105ea194980 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549b08ff5e93b809df01a6974598eabce902b5dca3bef8fdd0ae9f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1429bc785fdc4adc51006b72f574c963bc97309e22feb0b54f8b944292af3b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c74d5a471091962d858c65542df842172e2e95a85bfe0eea2c6be86c8bfd89 + +handshake=Noise_K_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545452dfe8670e01ec6c7ddf716617ac9e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=aca1ae00ed718c11ae8f91c3c289db54dca4fba284098248984158f4afb15a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=334cde4d2b9e7189be333e05c4e8ca8cbe9a7e9e3170dc61abf51906f95f9b + +handshake=Noise_Kpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254091a3df37d8ffa0d9c758bac64d545e2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7736979bc1fc8d5c7d42c92ea41ee59e97d59faafe791a2e3d58c8e8fb9929 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03236fadebc8f6a18ecb878d1ac2b78a3cf0e0024d0fb5d8b9d105ea194980 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625467fbf473495da6b5e23acf5bb6fe9b22 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1429bc785fdc4adc51006b72f574c963bc97309e22feb0b54f8b944292af3b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c74d5a471091962d858c65542df842172e2e95a85bfe0eea2c6be86c8bfd89 + +handshake=Noise_K_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625428f2b400a063dbdce02b5c28836b6e5fda2325068eb862efefce +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=aca1ae00ed718c11ae8f91c3c289db54dca4fba284098248984158f4afb15a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=334cde4d2b9e7189be333e05c4e8ca8cbe9a7e9e3170dc61abf51906f95f9b + +handshake=Noise_Kpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c2b61d59cbbc7e45c974869c028f5d84ed2aef938dd851ef00bd +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7736979bc1fc8d5c7d42c92ea41ee59e97d59faafe791a2e3d58c8e8fb9929 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03236fadebc8f6a18ecb878d1ac2b78a3cf0e0024d0fb5d8b9d105ea194980 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549b08ff5e93b809df01a6287cee688e3c750260ad541a39378ee2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1429bc785fdc4adc51006b72f574c963bc97309e22feb0b54f8b944292af3b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c74d5a471091962d858c65542df842172e2e95a85bfe0eea2c6be86c8bfd89 + +handshake=Noise_X_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625427b9e233a46e236bc3b949c842a23bd75b3d6d717dbf3aa4a3cfaa59a42e6a50f3540c9b1fdc8ca68fb6b8f9081e9b28194a52a70998dd4ec3fc2088ad06f966 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=601398a290497a3ecf22851d05f53b34fa1fc4a47a0371df1f5c540a1ecf61 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=04edfc327b91e91bb67f5a069e5afbf154ebcf196baf843dce5d22f58f04e7 + +handshake=Noise_Xpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254806e8e97beb9d15190981ce5f4080aeb28c7e1c743a3d676a62c14f688c70a7c7ea2fe760f1224179cc5e79e1e6510512dda2314f768816ac53546834a0e3615 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d3fabb12ea23bcec3493f543912515d7ad5ed8e58e9a9998ae5044d2f27c32 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5b47a6a68e47e6c22c90a55fb3bff11a8a0bbb84813887d2d7ba0e96dfd36c + +handshake=Noise_Xpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546fa09d3ca0fdbbc71df8bb16ff941b7488f0c070e770859b7026d4058df16697a5eb1d97cf498e8a907dd916557c3564006c7097ab7bb6106508c504c44b9cbc +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=48b987b047342448756adb8c63d3e45f96b4be90f221b0406ab00e95f7219c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=451d0097fdecb5f4a7e61ef341bdb66a8bbdaf5b1a650d05e7b0f5e29f26ac + +handshake=Noise_X_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625427b9e233a46e236bc3b949c842a23bd75b3d6d717dbf3aa4a3cfaa59a42e6a50f3540c9b1fdc8ca68fb6b8f9081e9b28ea4c05b652dbf8aff85830c628e63acd02c85425c685c650b07e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=601398a290497a3ecf22851d05f53b34fa1fc4a47a0371df1f5c540a1ecf61 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=04edfc327b91e91bb67f5a069e5afbf154ebcf196baf843dce5d22f58f04e7 + +handshake=Noise_Xpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254806e8e97beb9d15190981ce5f4080aeb28c7e1c743a3d676a62c14f688c70a7c7ea2fe760f1224179cc5e79e1e651051ab45b08deb5664fd49b358927839000e24fd90d598c3c57ee99d +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d3fabb12ea23bcec3493f543912515d7ad5ed8e58e9a9998ae5044d2f27c32 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5b47a6a68e47e6c22c90a55fb3bff11a8a0bbb84813887d2d7ba0e96dfd36c + +handshake=Noise_Xpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546fa09d3ca0fdbbc71df8bb16ff941b7488f0c070e770859b7026d4058df16697a5eb1d97cf498e8a907dd916557c3564f54ded2eef286aa4c8f398f33f44b433c3e830e471f72ed3db02 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=48b987b047342448756adb8c63d3e45f96b4be90f221b0406ab00e95f7219c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=451d0097fdecb5f4a7e61ef341bdb66a8bbdaf5b1a650d05e7b0f5e29f26ac + +handshake=Noise_X_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625427b9e233a46e236bc3b949c842a23bd75b3d6d717dbf3aa4a3cfaa59a42e6a50e9a53f4b77ba9c212a5ca41f911c099159e23701989c18e59ba9ffc746d06b61 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=601398a290497a3ecf22851d05f53b34fa1fc4a47a0371df1f5c540a1ecf61 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=04edfc327b91e91bb67f5a069e5afbf154ebcf196baf843dce5d22f58f04e7 + +handshake=Noise_Xpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254806e8e97beb9d15190981ce5f4080aeb28c7e1c743a3d676a62c14f688c70a7c70240353a0960993446dad6546c6a59e0df5ae06d7bc29f93ccdcc03a66ed9e5 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d3fabb12ea23bcec3493f543912515d7ad5ed8e58e9a9998ae5044d2f27c32 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5b47a6a68e47e6c22c90a55fb3bff11a8a0bbb84813887d2d7ba0e96dfd36c + +handshake=Noise_Xpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546fa09d3ca0fdbbc71df8bb16ff941b7488f0c070e770859b7026d4058df16697a6910630c6924a577f719acb8ee3181ca49a434aad229419e4f52a88ba17496e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=48b987b047342448756adb8c63d3e45f96b4be90f221b0406ab00e95f7219c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=451d0097fdecb5f4a7e61ef341bdb66a8bbdaf5b1a650d05e7b0f5e29f26ac + +handshake=Noise_X_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625427b9e233a46e236bc3b949c842a23bd75b3d6d717dbf3aa4a3cfaa59a42e6a50e9a53f4b77ba9c212a5ca41f911c0991ea4c05b652dbf8aff858319c0516c6e9079711b89e419c5825b1 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=601398a290497a3ecf22851d05f53b34fa1fc4a47a0371df1f5c540a1ecf61 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=04edfc327b91e91bb67f5a069e5afbf154ebcf196baf843dce5d22f58f04e7 + +handshake=Noise_Xpsk0_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254806e8e97beb9d15190981ce5f4080aeb28c7e1c743a3d676a62c14f688c70a7c70240353a0960993446dad6546c6a59eab45b08deb5664fd49b37733e0f59b46f6a5688e03dc408d5133 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d3fabb12ea23bcec3493f543912515d7ad5ed8e58e9a9998ae5044d2f27c32 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5b47a6a68e47e6c22c90a55fb3bff11a8a0bbb84813887d2d7ba0e96dfd36c + +handshake=Noise_Xpsk1_25519_AESGCM_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546fa09d3ca0fdbbc71df8bb16ff941b7488f0c070e770859b7026d4058df16697a6910630c6924a577f719acb8ee3181cf54ded2eef286aa4c8f37ef95f1e47c89dc3f7afa0b2effc7d5a +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=48b987b047342448756adb8c63d3e45f96b4be90f221b0406ab00e95f7219c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=451d0097fdecb5f4a7e61ef341bdb66a8bbdaf5b1a650d05e7b0f5e29f26ac + +handshake=Noise_NN_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466546c757b1dee39fe34639f8e59d36b90 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9a465eef7a497d636aacec6f177a46820045154c6dc21cc887158ff7178f5f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a889eab9dcbdd768c92201eb7092fb3e9e2d1c87321fe70f6bd261b21a9aa1 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544ee81f7b223bb25827a6c6c707001dd3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b0e7e624ccf4642b46e401e8b574cfa1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2c2a25a39ec72b321405393e10c51caec56f8da5af863eb3d5875cbc99afe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=31d8991d2ddb026d6ea7e4a1b1bf6388d87fa21d793547514f645d4724523a + +handshake=Noise_NNpsk1_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e4ed6d14e51cbd37289127ac1c818458 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846604d0bbf97d4b0d35616ddd8e3293e340 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=293dbf6b4293997b1f3609daa237dcf09ec2a79911ef69d311075b231f83cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89ef11a27e48c5d96b7d4562a8ef782ede9b361e0efe9faacc97c90d361058 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da9fb0ab9e465a7ae90061d62fc67048 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fa2036b0d82fc4c002454692a98cf138 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5375de65fffa56df1d6e3e66a913430fe313c3418fdeda2e43afb34efd29c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=979f3f045a786f9677281e84a4a5df198ec6a826f5969acc228ab6d1cda049 + +handshake=Noise_NN_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466295bdf92326b33d62ca816fc6e8d84b579611812fea2df8204c8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9a465eef7a497d636aacec6f177a46820045154c6dc21cc887158ff7178f5f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a889eab9dcbdd768c92201eb7092fb3e9e2d1c87321fe70f6bd261b21a9aa1 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437af6d133d63144ae694f990d6e209b9fc4b7cd0f5ca1307e06b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466823c7e1e048fa3767e86e0d471622865d0683936feec93cb113c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2c2a25a39ec72b321405393e10c51caec56f8da5af863eb3d5875cbc99afe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=31d8991d2ddb026d6ea7e4a1b1bf6388d87fa21d793547514f645d4724523a + +handshake=Noise_NNpsk1_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4d6af33ed485a97c7b78e7d1348afa4323f56148bcd00e812d4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664410c5cc3bcf499527e4b6a7df87d8b5007c28b75228d5a62a41 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=293dbf6b4293997b1f3609daa237dcf09ec2a79911ef69d311075b231f83cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89ef11a27e48c5d96b7d4562a8ef782ede9b361e0efe9faacc97c90d361058 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e1214c67afb95f49d730eb2108ee24b3d646e4aff196aafde03 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846646e5b3a50b77fce5d9d013a0cc1d6bb43389bd89bfae89fdffc6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5375de65fffa56df1d6e3e66a913430fe313c3418fdeda2e43afb34efd29c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=979f3f045a786f9677281e84a4a5df198ec6a826f5969acc228ab6d1cda049 + +handshake=Noise_NN_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf2b3d8441501153c7ad77fff102d4ad +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9a465eef7a497d636aacec6f177a46820045154c6dc21cc887158ff7178f5f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a889eab9dcbdd768c92201eb7092fb3e9e2d1c87321fe70f6bd261b21a9aa1 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e1f68ba6e11a996f2eaf8e6cb3b13ffa +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662175601186f38e8e4a7912983c06a531 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2c2a25a39ec72b321405393e10c51caec56f8da5af863eb3d5875cbc99afe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=31d8991d2ddb026d6ea7e4a1b1bf6388d87fa21d793547514f645d4724523a + +handshake=Noise_NNpsk1_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625400265a786349e17fbf3e17b4741a0f71 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ad5a7a0e7c3373008afa12e20e32f4bc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=293dbf6b4293997b1f3609daa237dcf09ec2a79911ef69d311075b231f83cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89ef11a27e48c5d96b7d4562a8ef782ede9b361e0efe9faacc97c90d361058 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540d8253a4f31ebf4711fa4bad845bf9d0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ec4107be3f3458a3c348dfda74cb2480 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5375de65fffa56df1d6e3e66a913430fe313c3418fdeda2e43afb34efd29c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=979f3f045a786f9677281e84a4a5df198ec6a826f5969acc228ab6d1cda049 + +handshake=Noise_NN_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466295bdf92326b33d62ca8984f94b14878d51ba9ce00d1d3ff8a2d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9a465eef7a497d636aacec6f177a46820045154c6dc21cc887158ff7178f5f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a889eab9dcbdd768c92201eb7092fb3e9e2d1c87321fe70f6bd261b21a9aa1 + +handshake=Noise_NNpsk0_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437af6d133d63144ae6948b6affd3e6efdabe0650147eedb0be22 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466823c7e1e048fa3767e86d07cedbf0af0e30b9bf2390a8a6891c5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2c2a25a39ec72b321405393e10c51caec56f8da5af863eb3d5875cbc99afe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=31d8991d2ddb026d6ea7e4a1b1bf6388d87fa21d793547514f645d4724523a + +handshake=Noise_NNpsk1_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4d6af33ed485a97c7b76404c4af6bd734344a8deb859a576eb0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664410c5cc3bcf499527e474b5995606d95c03e01d927792b13f20 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=293dbf6b4293997b1f3609daa237dcf09ec2a79911ef69d311075b231f83cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89ef11a27e48c5d96b7d4562a8ef782ede9b361e0efe9faacc97c90d361058 + +handshake=Noise_NNpsk2_25519_AESGCM_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e1214c67afb95f49d731e6796c13bf0aff823ea8ff9d0a0c167 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846646e5b3a50b77fce5d9d054b5a59fddb6f6f965ad8a102b98c3e7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5375de65fffa56df1d6e3e66a913430fe313c3418fdeda2e43afb34efd29c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=979f3f045a786f9677281e84a4a5df198ec6a826f5969acc228ab6d1cda049 + +handshake=Noise_KN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f72c1a277693fd38269f8a99291c5da2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f85b724b0d10b19b9f18ba74dc10bc28c187a1505e32a1b7ddb76fc381c60 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b27b15d8102e55eb6b5e7c02d5c1309289aa197b383424bb8d70268d1270f + +handshake=Noise_KNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544b68b11ecf5211c5fda412733efd29ca +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663cbd6e15bfac1b01f644ac427edfc442 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c41244c39a4dc4bbd816e4383b36aeb29b39b1a4cd3375c8ee7db0f744b131 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbcc5c8eedfe981223357f4d43f13be03b9c6ee905ad052bb319a97d31e22c + +handshake=Noise_KNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ed5eac382bc8e0e9fd781c2da8b87220 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466176a5de05f62ccb244d937a1aa4740e4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=90abc79cc783c1390801576ba8ef427a7cc56945b010efdd7b649ad1dbf654 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a414c63f43213f517dbe5b9ca2fe9013e406135d0b085f6718825d67d1b829 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c0bb61207231b261590226d6bd0ae06f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c2392623d2b637e821625b49207eeb58 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aaaeaecd7573c689b8d4ccbc5770cb22d0af475f726df807fc07e57aca7fe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1ee45b0cdba6411256525be9e7e44e1042d2c5402d080fdd0de28944e38b2a + +handshake=Noise_KN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d680843f299d5b026581d284e8e375b8d3fb53a0e005ce9714f7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f85b724b0d10b19b9f18ba74dc10bc28c187a1505e32a1b7ddb76fc381c60 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b27b15d8102e55eb6b5e7c02d5c1309289aa197b383424bb8d70268d1270f + +handshake=Noise_KNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c078e4e4c58ada7cb779610e8a2238b1012f7082cb66c772cfc9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ab8d646d386089d58257871d3f64ce46e5a812c674583d1ccdf4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c41244c39a4dc4bbd816e4383b36aeb29b39b1a4cd3375c8ee7db0f744b131 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbcc5c8eedfe981223357f4d43f13be03b9c6ee905ad052bb319a97d31e22c + +handshake=Noise_KNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254484735eb56d9c231711a4a49f1b0e91368939fe01abaafeda157 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466955eb77ae3722bb9b8c14c019d2261382b06c17e895bfe86f3dc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=90abc79cc783c1390801576ba8ef427a7cc56945b010efdd7b649ad1dbf654 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a414c63f43213f517dbe5b9ca2fe9013e406135d0b085f6718825d67d1b829 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254222c68cd4874356be9500e89b00ff544ace940b5729f086c3219 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f47863d9cb0059460bd645d3cf5c91821534a353e6358b048322 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aaaeaecd7573c689b8d4ccbc5770cb22d0af475f726df807fc07e57aca7fe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1ee45b0cdba6411256525be9e7e44e1042d2c5402d080fdd0de28944e38b2a + +handshake=Noise_KN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466edfd9f5e801b157d7af36200f0962b2a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f85b724b0d10b19b9f18ba74dc10bc28c187a1505e32a1b7ddb76fc381c60 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b27b15d8102e55eb6b5e7c02d5c1309289aa197b383424bb8d70268d1270f + +handshake=Noise_KNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254017d026ae69e905da4fa3527befbe8a1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c903feabcdd078005d691951aa948363 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c41244c39a4dc4bbd816e4383b36aeb29b39b1a4cd3375c8ee7db0f744b131 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbcc5c8eedfe981223357f4d43f13be03b9c6ee905ad052bb319a97d31e22c + +handshake=Noise_KNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d1ff777c50a19ec441934658f96590fb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846654b54d2e6cdea2573e3a4b7e84607e8f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=90abc79cc783c1390801576ba8ef427a7cc56945b010efdd7b649ad1dbf654 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a414c63f43213f517dbe5b9ca2fe9013e406135d0b085f6718825d67d1b829 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d845f0d6e394c2c4577a7543e7e781c4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665445832471db03c2530f8279f43e913b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aaaeaecd7573c689b8d4ccbc5770cb22d0af475f726df807fc07e57aca7fe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1ee45b0cdba6411256525be9e7e44e1042d2c5402d080fdd0de28944e38b2a + +handshake=Noise_KN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d680843f299d5b0265815e4064f0df3ea5eeef9535edc1a29e1b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f85b724b0d10b19b9f18ba74dc10bc28c187a1505e32a1b7ddb76fc381c60 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b27b15d8102e55eb6b5e7c02d5c1309289aa197b383424bb8d70268d1270f + +handshake=Noise_KNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c078e4e4c58ada7cb779bd109ef1e5c961b7ffb99ec6d65744b0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ab8d646d386089d5825772141b5d91cba7a101d5ce077f7eec01 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c41244c39a4dc4bbd816e4383b36aeb29b39b1a4cd3375c8ee7db0f744b131 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbcc5c8eedfe981223357f4d43f13be03b9c6ee905ad052bb319a97d31e22c + +handshake=Noise_KNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254484735eb56d9c231711a830caaff9108765bb21ac3cfc49d99eb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466955eb77ae3722bb9b8c17991fc2b411ec54030c87e11b2f67cf1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=90abc79cc783c1390801576ba8ef427a7cc56945b010efdd7b649ad1dbf654 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a414c63f43213f517dbe5b9ca2fe9013e406135d0b085f6718825d67d1b829 + +handshake=Noise_KNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254222c68cd4874356be9509397dc032d89ade799a5a2591d9a6b32 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f47863d9cb0059460bd69e5cf4f459a34ce682b7e725dbbedae3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aaaeaecd7573c689b8d4ccbc5770cb22d0af475f726df807fc07e57aca7fe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1ee45b0cdba6411256525be9e7e44e1042d2c5402d080fdd0de28944e38b2a + +handshake=Noise_NK_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f4de59ddee9ea99d5e8aa53446f9bac9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846600c26d78fb1fda00ee777962da982403 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c3b3e1a1b22cdec195cb8c43f3d694269cd55421d0895cca7696e8c298c1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=13d838829d7fb57425535f1586944638fc6bbf339797c76dca3220ef1ac3c6 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625442eba9e36fd2c74a614ad95028e3f5a0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c4add52345e59d58759ba764f67ed9bc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=977b3bc4c37ed85bb2f14db182740fe80d5f46a53fdc0a94ab5c45c457524e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c2b02468bfcafd95de5eb7f367545a23c4569540a3ad7c8f586f9df3906ca + +handshake=Noise_NKpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545bea413ae247b1489d5d76dc47a98732 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846680c1ccc3ceb11995d9a9c688519e916c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dafa613d0ecf78ca534bf648499e98d5d3b22807a64149f12b45f27b397b16 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=917876a5cd379ec833d3b8e3bae24aaba92e63c316d40872b543fb60f9ad16 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c4be6444813fede19be6aef74e85031c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846607ef2728f791c670472e5a41e1e6b31f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eaf9eace39e81e51a53ae9eabd917d2605ce13bdcf089338a62b554225f230 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d0c1580eea13c076581792052cc5ea1617c4093fd54657130b273ccb55f1b9 + +handshake=Noise_NK_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254479d6d76c8b559feebf4a71f42ce483ff0cf117f668906babd12 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846621612afe71fb7bc67dafcd0d83506c6becdad3daac83d5b90b24 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c3b3e1a1b22cdec195cb8c43f3d694269cd55421d0895cca7696e8c298c1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=13d838829d7fb57425535f1586944638fc6bbf339797c76dca3220ef1ac3c6 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625410bac85a9bf99c7fdd478913e038b7ccc97518c9cad9e1533646 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e2cc032cc4ae7da4eda9f47aa7c37ad99015588c190bac9a8387 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=977b3bc4c37ed85bb2f14db182740fe80d5f46a53fdc0a94ab5c45c457524e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c2b02468bfcafd95de5eb7f367545a23c4569540a3ad7c8f586f9df3906ca + +handshake=Noise_NKpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625482751e4f02de3f742d89f17b30414fb1151dd7eb34dba83103cf +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664376773ce777a22ce76c89b02c0c992849ecf119f5ecddb511c6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dafa613d0ecf78ca534bf648499e98d5d3b22807a64149f12b45f27b397b16 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=917876a5cd379ec833d3b8e3bae24aaba92e63c316d40872b543fb60f9ad16 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542d0dcc1bd68cfc5ae3bd0b87c08f23c69ce1b3cccd83f5204db1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466df4695624544314012baea976075677efc6eb4417112883ebd7c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eaf9eace39e81e51a53ae9eabd917d2605ce13bdcf089338a62b554225f230 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d0c1580eea13c076581792052cc5ea1617c4093fd54657130b273ccb55f1b9 + +handshake=Noise_NK_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bccd4635d2891ae46fa388fcb277b5bb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668479b6648e2a13c0900168a46748457f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c3b3e1a1b22cdec195cb8c43f3d694269cd55421d0895cca7696e8c298c1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=13d838829d7fb57425535f1586944638fc6bbf339797c76dca3220ef1ac3c6 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625446261dfdaaf4ca0a1e51254bbf6b3a71 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1fae0771c98fdec558518fc919cbd4f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=977b3bc4c37ed85bb2f14db182740fe80d5f46a53fdc0a94ab5c45c457524e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c2b02468bfcafd95de5eb7f367545a23c4569540a3ad7c8f586f9df3906ca + +handshake=Noise_NKpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ac3a9c9d8550f06f3de2b891e96395cb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bf809f989b8fbf9c10f6d31438caa613 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dafa613d0ecf78ca534bf648499e98d5d3b22807a64149f12b45f27b397b16 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=917876a5cd379ec833d3b8e3bae24aaba92e63c316d40872b543fb60f9ad16 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9b01234febc4f0392461ae38c5ee4a8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846661ff269ec62bf942fe8d6c85a773b1d2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eaf9eace39e81e51a53ae9eabd917d2605ce13bdcf089338a62b554225f230 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d0c1580eea13c076581792052cc5ea1617c4093fd54657130b273ccb55f1b9 + +handshake=Noise_NK_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254479d6d76c8b559feebf467ad4b7003f368eb3929dca92e160bad +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846621612afe71fb7bc67daf8931a9010b74ab201a6ab9a6224cc78d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c3b3e1a1b22cdec195cb8c43f3d694269cd55421d0895cca7696e8c298c1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=13d838829d7fb57425535f1586944638fc6bbf339797c76dca3220ef1ac3c6 + +handshake=Noise_NKpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625410bac85a9bf99c7fdd476360ac387c559fc40fa57bc0de8f2b03 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e2cc032cc4ae7da4eda923f9aad27b1e981be207dc57be28e47c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=977b3bc4c37ed85bb2f14db182740fe80d5f46a53fdc0a94ab5c45c457524e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c2b02468bfcafd95de5eb7f367545a23c4569540a3ad7c8f586f9df3906ca + +handshake=Noise_NKpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625482751e4f02de3f742d89bba6ef6aea9975aae58faccbb8541cf7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664376773ce777a22ce76c25463e4d298635ca65941beae4337859 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dafa613d0ecf78ca534bf648499e98d5d3b22807a64149f12b45f27b397b16 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=917876a5cd379ec833d3b8e3bae24aaba92e63c316d40872b543fb60f9ad16 + +handshake=Noise_NKpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542d0dcc1bd68cfc5ae3bd27ac7960aa606e9dec412a6c64323ea2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466df4695624544314012ba66257a4a39bb5b6289e32409329b7bda +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eaf9eace39e81e51a53ae9eabd917d2605ce13bdcf089338a62b554225f230 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d0c1580eea13c076581792052cc5ea1617c4093fd54657130b273ccb55f1b9 + +handshake=Noise_KK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cbe8f77ad210ff754922c56591edaf17 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b9198d85a19fe670094c3f65b567f3b5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6b689fca5f9af8029b40d692f66dab834d9b1ad71ef02e12f0ec068a93ba55 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=126650ec27e76d0de04fc556ef662a4a0cd619b62daacd5110dc43bfe1c1ba + +handshake=Noise_KKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cfc494240128ca1a452dedf604a4aa1c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e88e00d5fc2996457fd334c4f011f7cc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d15b43ffc8c33b514f6b1d1cb5a9baac7bb9e8ab7fa60db501342d4369c737 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6bd6bdae40d6880a9cf6572e48db7cde278aa1dedd855791167a093d62b2dc + +handshake=Noise_KKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437534665c31a179f15fb392f7617e6b4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846651a78581524074d4053423c2a7380160 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5ee8fab16de07e20d98cd7a3cfcd72d229520670746f1fcaaa1127c729994d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ee6791cd8c9a12ecd260c7efcf6d0b094f05828949743f7f1da36d2fead3bd + +handshake=Noise_KKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625493708ed5d90a001924c0e673e87cb122 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669f5abbd68865b250dfbf71912d44074b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0304f4a07a39789848204b1ac1fe2004f035cbb474b1e3f4f11b6f09aaff19 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=14bb951739a8ed231acc6348dcbe342ea124dd4d53a4a463ef415ebd15cb0d + +handshake=Noise_KK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254983397660911ddae03feba9474c170c3f303fd4d39625083903a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466beeba4b2e28bbb5d84eea1eb61d690d124b95b3c9f26a166fb5f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6b689fca5f9af8029b40d692f66dab834d9b1ad71ef02e12f0ec068a93ba55 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=126650ec27e76d0de04fc556ef662a4a0cd619b62daacd5110dc43bfe1c1ba + +handshake=Noise_KKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625432687ae9f41a125bbb260be5b0199fb6934a0986470429e21cc4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466678c53d1c8fb7d77e1c7ad887a31a56e2c7281c1bcb3bd549a7d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d15b43ffc8c33b514f6b1d1cb5a9baac7bb9e8ab7fa60db501342d4369c737 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6bd6bdae40d6880a9cf6572e48db7cde278aa1dedd855791167a093d62b2dc + +handshake=Noise_KKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b75e1a1de629bd7bac048614be9ce38bd0c0f0100160ff1dcd5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664bf2a2da8c86239618ed75c5a3a80f84f18e853c86a6c6137b98 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5ee8fab16de07e20d98cd7a3cfcd72d229520670746f1fcaaa1127c729994d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ee6791cd8c9a12ecd260c7efcf6d0b094f05828949743f7f1da36d2fead3bd + +handshake=Noise_KKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254797f85753395023883c29179f22e141c07c0d0940712f6c0224f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663fc5041accf40fbcf106a268de93fd43bd8ce67eec5bec522977 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0304f4a07a39789848204b1ac1fe2004f035cbb474b1e3f4f11b6f09aaff19 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=14bb951739a8ed231acc6348dcbe342ea124dd4d53a4a463ef415ebd15cb0d + +handshake=Noise_KK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625481294976bf2915b8d25846e070a8faf3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846683c72d35f421d61ea833ffb5a5ececc1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6b689fca5f9af8029b40d692f66dab834d9b1ad71ef02e12f0ec068a93ba55 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=126650ec27e76d0de04fc556ef662a4a0cd619b62daacd5110dc43bfe1c1ba + +handshake=Noise_KKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545511775bf252b7b7798b5aa47a6d2bf4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e6927b5da0967848b5cca6d9441ea950 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d15b43ffc8c33b514f6b1d1cb5a9baac7bb9e8ab7fa60db501342d4369c737 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6bd6bdae40d6880a9cf6572e48db7cde278aa1dedd855791167a093d62b2dc + +handshake=Noise_KKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254782f9ea5e938f3a83cd596e21dc38f26 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466108c204a27ee44abec42ab2e2155c7f1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5ee8fab16de07e20d98cd7a3cfcd72d229520670746f1fcaaa1127c729994d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ee6791cd8c9a12ecd260c7efcf6d0b094f05828949743f7f1da36d2fead3bd + +handshake=Noise_KKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546cfe8fea278b52605acdaed61a076cff +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661aea6d52c5f57bdb87846f3b20633e01 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0304f4a07a39789848204b1ac1fe2004f035cbb474b1e3f4f11b6f09aaff19 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=14bb951739a8ed231acc6348dcbe342ea124dd4d53a4a463ef415ebd15cb0d + +handshake=Noise_KK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254983397660911ddae03fe246b376afbd5d094b0fa701a84bdcd3e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466beeba4b2e28bbb5d84ee8142c6b37c508edf518dbad16a09b062 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6b689fca5f9af8029b40d692f66dab834d9b1ad71ef02e12f0ec068a93ba55 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=126650ec27e76d0de04fc556ef662a4a0cd619b62daacd5110dc43bfe1c1ba + +handshake=Noise_KKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625432687ae9f41a125bbb266304cfeeda44b8ac9eb1338ef6f186a7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466678c53d1c8fb7d77e1c79d4704436e55e97648d81807db8a43ba +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d15b43ffc8c33b514f6b1d1cb5a9baac7bb9e8ab7fa60db501342d4369c737 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6bd6bdae40d6880a9cf6572e48db7cde278aa1dedd855791167a093d62b2dc + +handshake=Noise_KKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b75e1a1de629bd7bac046d9df733cd3c96d735b2b5338c09281 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664bf2a2da8c86239618ed437962b82a34484359e590b7252d01b7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5ee8fab16de07e20d98cd7a3cfcd72d229520670746f1fcaaa1127c729994d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ee6791cd8c9a12ecd260c7efcf6d0b094f05828949743f7f1da36d2fead3bd + +handshake=Noise_KKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254797f85753395023883c2c7495a1b13f1976fa9ebbf898a1054d0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663fc5041accf40fbcf106a311f7eaa3ab0eb5bef5f28fa9ef0055 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0304f4a07a39789848204b1ac1fe2004f035cbb474b1e3f4f11b6f09aaff19 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=14bb951739a8ed231acc6348dcbe342ea124dd4d53a4a463ef415ebd15cb0d + +handshake=Noise_NX_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ac104e4413b3e6091ab98f8902f898f750341010fc28130905edcfa84df5b5ff78b8851e94c6c17bd270a7a37e6708c2d69210ebf8c5da2c7babd825d14ba61a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=50f23b250835f62aeee57429ea276cce9ce465b1fa5bd01cb8041bc9ae7722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=681c16d92b2ed840ea2096ee1445c6d699f71659c0aa98c115fd2be24a4e6a + +handshake=Noise_NXpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254128719fddfb85978a91462e8016a3b7c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666c4fbd20d2daae06cfee3a4044de5f045844d2d23c127c77abb5006a1727e9b0d65cf665ef2c2cf4b9b6abc1b2eb38c3795451e327b76fb59eb66315301bc415 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8a9c8176161c87470eb1bbe4a5ffe8bd08cc293b80f57f244c10ddbbe368d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=38d5a75a6dd18e71d5f6555c7edeac938ed79a312ac10077fd8fc8d82ad81b + +handshake=Noise_NXpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f68a3d756a50740b15842b4246d40c9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661d6f6e3ddf23875e0592cb924daf3d8126d3008e0d245a8ced1dbfb1286387dedccda427697bf1517a2ce36d5d4dfab9647ec2d26dee1cf6281f4b3217c2e7be +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0253fb688077f49bb12859d7f33c3988a23b855e14bb9963008bb5e8ada039 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d296bf8aac74a67761c7c5666f2922d68ab6e431aa6b4004b9fd8cd626cbee + +handshake=Noise_NXpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a3a8c0e25d9cbfd7880c6d3feacf6066 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fc485d9c0d76abdbc722684433571ab05ce22a12c92fb1ef81296edd14429f57af4cb353cb580e67a53f1d03fc6c7bede73fcb3b753dc767dfc38016c3dc3102 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b285956fce83786691fb9e5a48f6571ee16435da742caa84e27606c8c0417 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=43a9eb08fe5a95969a4eb076b238e5eba3913319b0b74142bc47a35b1fcace + +handshake=Noise_NX_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ac104e4413b3e6091ab98f8902f898f750341010fc28130905edcfa84df5b5ff50d0f6181f350f6b280c29e87598a257ff5df3365fc12cae7322ea77df156a499836d833f1c218000c9f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=50f23b250835f62aeee57429ea276cce9ce465b1fa5bd01cb8041bc9ae7722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=681c16d92b2ed840ea2096ee1445c6d699f71659c0aa98c115fd2be24a4e6a + +handshake=Noise_NXpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c087d6fe10c8862ed749092cff7288bbb82d14d6c00f86f0974 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666c4fbd20d2daae06cfee3a4044de5f045844d2d23c127c77abb5006a1727e9b07e867dd2c4ea66642d27c3ae9feeaea47089b9aede3e5674a1829bd4a5d8b3b057de516d4bf5318a2fa9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8a9c8176161c87470eb1bbe4a5ffe8bd08cc293b80f57f244c10ddbbe368d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=38d5a75a6dd18e71d5f6555c7edeac938ed79a312ac10077fd8fc8d82ad81b + +handshake=Noise_NXpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549b88c66c5db16c076955495c7289c3499a801ca5a1840f075d1e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661d6f6e3ddf23875e0592cb924daf3d8126d3008e0d245a8ced1dbfb1286387de90ab182bc2fb03dd6955f7ae27b74c7077b45b9ff2a8c8130a47ece321f582f42765af8ce6cecc9dab7f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0253fb688077f49bb12859d7f33c3988a23b855e14bb9963008bb5e8ada039 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d296bf8aac74a67761c7c5666f2922d68ab6e431aa6b4004b9fd8cd626cbee + +handshake=Noise_NXpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dad9df4c8fe65e76706807c4b6f3261a2ab9dd864826a4105018 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fc485d9c0d76abdbc722684433571ab05ce22a12c92fb1ef81296edd14429f57352b4c17d9ec7183cafe3bed352923f60758d553d3fe9be0c2f52ed6cbe5bc8146067bee786a4921f2b4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b285956fce83786691fb9e5a48f6571ee16435da742caa84e27606c8c0417 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=43a9eb08fe5a95969a4eb076b238e5eba3913319b0b74142bc47a35b1fcace + +handshake=Noise_NX_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ac104e4413b3e6091ab98f8902f898f750341010fc28130905edcfa84df5b5fffd5c64064a663cc1f8f0e59775f3d93db4e7d95dd77b5928935227a3bbfef59a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=50f23b250835f62aeee57429ea276cce9ce465b1fa5bd01cb8041bc9ae7722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=681c16d92b2ed840ea2096ee1445c6d699f71659c0aa98c115fd2be24a4e6a + +handshake=Noise_NXpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545386451c97b61e92eddb55d435aa604f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666c4fbd20d2daae06cfee3a4044de5f045844d2d23c127c77abb5006a1727e9b0fb77c4cfa310f7eb93a6b23b45f1c6dfc7b695808fdeb14bbcdf420040e859a3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8a9c8176161c87470eb1bbe4a5ffe8bd08cc293b80f57f244c10ddbbe368d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=38d5a75a6dd18e71d5f6555c7edeac938ed79a312ac10077fd8fc8d82ad81b + +handshake=Noise_NXpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6b06ac4ec214355f45fa8353f935109 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661d6f6e3ddf23875e0592cb924daf3d8126d3008e0d245a8ced1dbfb1286387de45b77dee817b10ee56198c4aeb08eaf24446e360a7d53fff28c2d680bbfd97ae +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0253fb688077f49bb12859d7f33c3988a23b855e14bb9963008bb5e8ada039 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d296bf8aac74a67761c7c5666f2922d68ab6e431aa6b4004b9fd8cd626cbee + +handshake=Noise_NXpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254006ef9622a9fef1a70a559a801e0b3c5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fc485d9c0d76abdbc722684433571ab05ce22a12c92fb1ef81296edd14429f571c5eeee49093a423c6b4acd63e27a510e1abef38197787ac2ec2d692f837e495 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b285956fce83786691fb9e5a48f6571ee16435da742caa84e27606c8c0417 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=43a9eb08fe5a95969a4eb076b238e5eba3913319b0b74142bc47a35b1fcace + +handshake=Noise_NX_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ac104e4413b3e6091ab98f8902f898f750341010fc28130905edcfa84df5b5ff10abab009c4e0ae9e6fe931c4b3a2db2ff5df3365fc12cae7322c0d6356a6fd2ae2b72c9b68520749403 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=50f23b250835f62aeee57429ea276cce9ce465b1fa5bd01cb8041bc9ae7722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=681c16d92b2ed840ea2096ee1445c6d699f71659c0aa98c115fd2be24a4e6a + +handshake=Noise_NXpsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c087d6fe10c8862ed7448bb4f10327d492edf33de25e98a29f0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666c4fbd20d2daae06cfee3a4044de5f045844d2d23c127c77abb5006a1727e9b0cb6829c168ec40755cb9791148c71e9b7089b9aede3e5674a182ddb40f356db56ba4f9af3bd611e9c363 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8a9c8176161c87470eb1bbe4a5ffe8bd08cc293b80f57f244c10ddbbe368d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=38d5a75a6dd18e71d5f6555c7edeac938ed79a312ac10077fd8fc8d82ad81b + +handshake=Noise_NXpsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549b88c66c5db16c0769556dd7aaeacf1e9daf99473ed45b7449e5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661d6f6e3ddf23875e0592cb924daf3d8126d3008e0d245a8ced1dbfb1286387de97e23ace6ec8210a1f5045c76214305477b45b9ff2a8c8130a47b7170d66956ae33fd7bcce1e8df4c94f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0253fb688077f49bb12859d7f33c3988a23b855e14bb9963008bb5e8ada039 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d296bf8aac74a67761c7c5666f2922d68ab6e431aa6b4004b9fd8cd626cbee + +handshake=Noise_NXpsk2_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dad9df4c8fe65e767068bdb6e296baddfa4c82b21bbcc228d06f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fc485d9c0d76abdbc722684433571ab05ce22a12c92fb1ef81296edd14429f57ee712f3e89a116cf1ad6e3ad414d7a320758d553d3fe9be0c2f5b3bf317650ef3f796be8958b8619f595 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b285956fce83786691fb9e5a48f6571ee16435da742caa84e27606c8c0417 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=43a9eb08fe5a95969a4eb076b238e5eba3913319b0b74142bc47a35b1fcace + +handshake=Noise_KX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672f4561972c0066d2edb9ec3f6e06061d9efd85e8e09eea4f7b55e051881ed2d461f07a142019054861b74148fc944f2e8d3d02e24ba2ac639ffb67a06cf941c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b455e7160f810c5bc83b94c63932a10a218f6558daa7c9408d619d960d2796 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2afc54621ee01e366836724674abfef6e64777e77ec15067c04d59d9209a4 + +handshake=Noise_KXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548430ae3a453831ae8a72cf799518925e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846616cadc6a5849f99f04d636b30b52105083d64100bee3bb0069b4f03ee5528920b0e6c7d5cd255c95ce396140e6463b697b3fef9bb639280d1e8ef58e2cc57896 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95f4eba61bd217fca6eeac0a5a0a96f68e11a0d0c49dd2e288a8e4e2b17feb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7df0beb173488e9c5778a1af08cbff1aa3337839a0ece825a2a502a0b05bc0 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545c23b090b7eba082e987ffde36222281 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea2829785aa59d7e2f1df56d98f6239f2a267a4c2001acb54d556932c40595e08d08fa0a460ac311e155c1961457907cc0a4d7e1108630ca5899c30604b20475 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=db708006c85bb5c1cdb6fab482f0179cb466ef1ac02d2a5d897ab5e93cda4e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2c4b83b0a27cce3a7347e01d5d11e47a2979bc41d5b8c4b7419640ef6afd + +handshake=Noise_KXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625450e8db962a84fca6873e83064a5444db +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846661d4c7b7bc2b1ee4596b72cc8f00e533cfe7c236f9b8deb95ad7fd92c14165e5a8d3903706ccda48ece8fff18fd25fcbc7742a1ecbd81dee525c0bc58eb20fe0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=41c1facc56421dd154d1435a4f33d5b5a243d389e0b460bdf6ea6362a8dcb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3aaefa2606543d87e25894c5eaed9eed40ceca80106c62822593046c03ae39 + +handshake=Noise_KX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672f4561972c0066d2edb9ec3f6e06061d9efd85e8e09eea4f7b55e051881ed2d3c473a344d1071574c284e14408c92b58539d798b2be574927e85b225447321ee1eca1a9e701c541dfc4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b455e7160f810c5bc83b94c63932a10a218f6558daa7c9408d619d960d2796 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2afc54621ee01e366836724674abfef6e64777e77ec15067c04d59d9209a4 + +handshake=Noise_KXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541a278e53378151225fdc24a27a0350908629f692f9235d8b579a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846616cadc6a5849f99f04d636b30b52105083d64100bee3bb0069b4f03ee55289202bbe89689c2b31e623a1ff6083a686213eb28814fe4ae279902deca97b1bf6dd106c9b325fda721e8e45 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95f4eba61bd217fca6eeac0a5a0a96f68e11a0d0c49dd2e288a8e4e2b17feb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7df0beb173488e9c5778a1af08cbff1aa3337839a0ece825a2a502a0b05bc0 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541963a6cc03347872d41cd292b29b87d22c488ec89f15cadc0304 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea2829785aa59d7e2f1df56d98f6239f2a267a4c2001acb54d556932c40595e0ff2d81ce4e2b85ccd5b50e3d9385951e978f1e633d310614bfa6c9af1eb5389105299f943c88ef268de0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=db708006c85bb5c1cdb6fab482f0179cb466ef1ac02d2a5d897ab5e93cda4e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2c4b83b0a27cce3a7347e01d5d11e47a2979bc41d5b8c4b7419640ef6afd + +handshake=Noise_KXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b687a1a128f62ce6ad4869118737b15a42084f3c92aebc30d267 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846661d4c7b7bc2b1ee4596b72cc8f00e533cfe7c236f9b8deb95ad7fd92c14165e50a8d064f224ac761b6d7c1c6c8eb50293f03deb388775b780f1a4d2ab7129b40773b857884e7fa3781ba +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=41c1facc56421dd154d1435a4f33d5b5a243d389e0b460bdf6ea6362a8dcb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3aaefa2606543d87e25894c5eaed9eed40ceca80106c62822593046c03ae39 + +handshake=Noise_KX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672f4561972c0066d2edb9ec3f6e06061d9efd85e8e09eea4f7b55e051881ed2d1d615544c66e1cb785f80a256fa65b2fa178f825837d657176e150e7ce6f245c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b455e7160f810c5bc83b94c63932a10a218f6558daa7c9408d619d960d2796 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2afc54621ee01e366836724674abfef6e64777e77ec15067c04d59d9209a4 + +handshake=Noise_KXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f158d8a926103237627624b7994e5cea +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846616cadc6a5849f99f04d636b30b52105083d64100bee3bb0069b4f03ee55289209cd64d6c3bbcf800f969aa8df01d86fe7072004c1b4554700eb5909209e0dab7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95f4eba61bd217fca6eeac0a5a0a96f68e11a0d0c49dd2e288a8e4e2b17feb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7df0beb173488e9c5778a1af08cbff1aa3337839a0ece825a2a502a0b05bc0 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d791c8f0b6f7c80957817be26d2892d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea2829785aa59d7e2f1df56d98f6239f2a267a4c2001acb54d556932c40595e00680a79b2539691fef9292119bcf76716a9952ab10be0f6024bf192f1769921a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=db708006c85bb5c1cdb6fab482f0179cb466ef1ac02d2a5d897ab5e93cda4e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2c4b83b0a27cce3a7347e01d5d11e47a2979bc41d5b8c4b7419640ef6afd + +handshake=Noise_KXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9a3396c47f801921ad02dbae48fc985 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846661d4c7b7bc2b1ee4596b72cc8f00e533cfe7c236f9b8deb95ad7fd92c14165e594f70660f3cee9026c4f1dbad7e0f4ad0cbf817f2b3cb5e211e95723c228e6a8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=41c1facc56421dd154d1435a4f33d5b5a243d389e0b460bdf6ea6362a8dcb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3aaefa2606543d87e25894c5eaed9eed40ceca80106c62822593046c03ae39 + +handshake=Noise_KX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672f4561972c0066d2edb9ec3f6e06061d9efd85e8e09eea4f7b55e051881ed2dc41c3031529d4ad19d8b7d219ee949ba8539d798b2be574927e893bc2be2e90d5f23a332ce63e9b6af53 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b455e7160f810c5bc83b94c63932a10a218f6558daa7c9408d619d960d2796 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2afc54621ee01e366836724674abfef6e64777e77ec15067c04d59d9209a4 + +handshake=Noise_KXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541a278e53378151225fdcdac5afdbdd2dc7dedc8295b2873efbe7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846616cadc6a5849f99f04d636b30b52105083d64100bee3bb0069b4f03ee55289203975f934fe65246ce4d017fc344204863eb28814fe4ae279902d812f17f5fdeec17d2be7cfe9c15fe371 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=95f4eba61bd217fca6eeac0a5a0a96f68e11a0d0c49dd2e288a8e4e2b17feb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7df0beb173488e9c5778a1af08cbff1aa3337839a0ece825a2a502a0b05bc0 + +handshake=Noise_KXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541963a6cc03347872d41c5e0ed0f6f3e8e1bb772a98ffc1f921a3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea2829785aa59d7e2f1df56d98f6239f2a267a4c2001acb54d556932c40595e0add7a52cc2a82263c610384ed971faaf978f1e633d310614bfa6c7981a371f1daaf7743d4b65531bfac4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=db708006c85bb5c1cdb6fab482f0179cb466ef1ac02d2a5d897ab5e93cda4e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2c4b83b0a27cce3a7347e01d5d11e47a2979bc41d5b8c4b7419640ef6afd + +handshake=Noise_KXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b687a1a128f62ce6ad483da6460c40931a96fa6bd046991ec6fa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846661d4c7b7bc2b1ee4596b72cc8f00e533cfe7c236f9b8deb95ad7fd92c14165e5c17fef40ec942d9af58b9f2084f7d7343f03deb388775b780f1a06a1f31cd098cde068559214e75a9613 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=41c1facc56421dd154d1435a4f33d5b5a243d389e0b460bdf6ea6362a8dcb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3aaefa2606543d87e25894c5eaed9eed40ceca80106c62822593046c03ae39 + +handshake=Noise_XN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667ebc7d2d516cca269396ef67d295ec39 +msg_2_payload= +msg_2_ciphertext=1ab983aef2af5558802d787fec340c612a9332b5ad54d9d76bea87516becc239cae582f922483a710bdadf4d3d4104b83912d0022b4c80366819f93508567e42 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d195f8befc66baa201a18c4064909ebe8502e0f9b5e961314b61fd125d247d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86591937ccc7873fb61286c7d019e73daf8b40ec33dcc9d1fffe1c9a16dd4c + +handshake=Noise_XNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d6ce88b9c3416bd1b1fd48bd564b7d8b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662736201c798b5d138492b71ca9303c38 +msg_2_payload= +msg_2_ciphertext=b1fa0b5e1310eb981ee2e54af06f5f88b5a9d0140be4b3bc6b2946a937e40d7ffcc250ffbcda3b2f9620ebf6eac14a59a1210630e2445733f2e46646501b9357 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=553b9158015420d2b4692c4b30b0fb26ade7adfa1fcbcc182e90b7244054b3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2383835c704affed54b3525f4d7f63064538ce838cd706c9197aff8881fb31 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254967f2f01403b1579c67ebc37850a3984 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667d7227bc0115068aaaad4d8b7fc66cdb +msg_2_payload= +msg_2_ciphertext=8d7c08550caffdd7302901d1ef368326f22321a4511debccbbd532ccb7d96f286ec78fbd90058b6b4e4a015560082c19ca281643f095da37cf820411c2d087d0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=eb2dbb2a68310558e3a1ca71a2257cd6f28ddfd99fa854dc8011d812e90101 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=80c84ea17aa9f0d18602ab87eb20259a858074a95e5f076907e632667db5fb + +handshake=Noise_XNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546ca3cd19431029b33d5dca3bc873f8bb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e0071d3b01d6039361134ab45ac8b078 +msg_2_payload= +msg_2_ciphertext=57d0d36040aea7cc919054c726a651796718f907af000923de50022aac735ff60d17220a0c76cc92c0f6fbd59b2137d761b604bd4022323157834edcf5e479a9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=078228238d9d65d53d9910156e32b61af70cac329a27000c3968d942f325af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=eaa3e5c640ca8998164b6fa6e2c3546393076d09e3f87493d20b91f3fbadd2 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547cbc94fd1c4c0d0998ff4e6d7a365759 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a9868d34a16223d571df967ef2c2a815 +msg_2_payload= +msg_2_ciphertext=83cbff8b883cab6302654c8d6d6e50a3e7323d9024018c648cf98824f0e880ab5995de92829e6723630bac7f2f6ab19656155b0561d7998e25c283903c34fece +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=62620d455bce603e36d0e324deb5ae87a2a3ac98b56a0de4b3cd02e98e285e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=37668ce320aa3b29cd5dd49bfc5fd63474ff03fade3bf0dde6164fa0030b64 + +handshake=Noise_XN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669bc42f905f6cea8c6d21736310fecc3db8d9b6e67b39bdfeaf21 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=1ab983aef2af5558802d787fec340c612a9332b5ad54d9d76bea87516becc239d9d0e972486a926167ac22ff38795bb8d5ff457d78cb9ee139f97cf0aa00153beac61936bd612bd689fe +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d195f8befc66baa201a18c4064909ebe8502e0f9b5e961314b61fd125d247d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86591937ccc7873fb61286c7d019e73daf8b40ec33dcc9d1fffe1c9a16dd4c + +handshake=Noise_XNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254383b83be44ec842dd3006898b7004b470de5cd728369d9d0bbb7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665933b46f951a73becfa372a5ae6db01ed6238a0edb6dbf4c6cd4 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b1fa0b5e1310eb981ee2e54af06f5f88b5a9d0140be4b3bc6b2946a937e40d7faf234bc6d125f13bbc03b3123995036cb9e89a78f9efa643f1cdd386afe537a04caf8573a64da952a302 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=553b9158015420d2b4692c4b30b0fb26ade7adfa1fcbcc182e90b7244054b3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2383835c704affed54b3525f4d7f63064538ce838cd706c9197aff8881fb31 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447a625a9ed5dd10375d8ee2e1a8b6de55f4bb41c7afd0ba7530f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661977595c1b822311d2db73d33c2217e9e61c48015261e4bf2ccb +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8d7c08550caffdd7302901d1ef368326f22321a4511debccbbd532ccb7d96f28a88b4c55350214e5105354ff79021a3346fe0bfca84667d86819739dbee501a7a7ad383e6ac4fc93d3a4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=eb2dbb2a68310558e3a1ca71a2257cd6f28ddfd99fa854dc8011d812e90101 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=80c84ea17aa9f0d18602ab87eb20259a858074a95e5f076907e632667db5fb + +handshake=Noise_XNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540dc8226f2f99fa7085ced52daea87b8eba61c0a8bceba13e8296 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9fd0e03c736f0dbe83784fd835dbcccc6aa205422101c0b7562 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=57d0d36040aea7cc919054c726a651796718f907af000923de50022aac735ff6dc185e9cc4a822dc22082b1e9c705d953214f3e01388aa3cd4912e5cde0319b158974a4c910c12436a81 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=078228238d9d65d53d9910156e32b61af70cac329a27000c3968d942f325af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=eaa3e5c640ca8998164b6fa6e2c3546393076d09e3f87493d20b91f3fbadd2 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546c1aa61ab88ff9a43d1c80d505b1c6efb80ce50a5643b362d0df +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661588ca3f0797a06d1b63b044f56d827811dcbc1f646a8def6f2d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=83cbff8b883cab6302654c8d6d6e50a3e7323d9024018c648cf98824f0e880abe8fa324069e8d159ca0a8dc4b0cafdecd4d7fe0f1353b05c118a548b145e78bb26f3b9d520fe9b4d1514 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=62620d455bce603e36d0e324deb5ae87a2a3ac98b56a0de4b3cd02e98e285e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=37668ce320aa3b29cd5dd49bfc5fd63474ff03fade3bf0dde6164fa0030b64 + +handshake=Noise_XN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9e8710f7b46475111899a331cb6d0a7 +msg_2_payload= +msg_2_ciphertext=1ab983aef2af5558802d787fec340c612a9332b5ad54d9d76bea87516becc239067cd1d54113d19c1f71c83a1edf288d743f8a931b93cb162a125f6042ef548f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d195f8befc66baa201a18c4064909ebe8502e0f9b5e961314b61fd125d247d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86591937ccc7873fb61286c7d019e73daf8b40ec33dcc9d1fffe1c9a16dd4c + +handshake=Noise_XNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547a92e7a29e352f7a1fdbf917a7d408fb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c95d0a8a41a3cfbe098066ef8799cedc +msg_2_payload= +msg_2_ciphertext=b1fa0b5e1310eb981ee2e54af06f5f88b5a9d0140be4b3bc6b2946a937e40d7f7c035f20b8c89981b5d78bd802ffcbf57049af8a3bf01842bf9401424fbc2522 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=553b9158015420d2b4692c4b30b0fb26ade7adfa1fcbcc182e90b7244054b3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2383835c704affed54b3525f4d7f63064538ce838cd706c9197aff8881fb31 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549e5174a2db0e02e89ce6700b7f724e98 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e3f9c5d3216d0bbc1c9732c02fb6d958 +msg_2_payload= +msg_2_ciphertext=8d7c08550caffdd7302901d1ef368326f22321a4511debccbbd532ccb7d96f2866581032bd9ef4ec605c89f9a9c11d3c934b44c76b19fb9e874055521d8c2126 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=eb2dbb2a68310558e3a1ca71a2257cd6f28ddfd99fa854dc8011d812e90101 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=80c84ea17aa9f0d18602ab87eb20259a858074a95e5f076907e632667db5fb + +handshake=Noise_XNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625463a521446358f262e7d5a60de7721239 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b360a6b915076e4a46f0df191ef44a2a +msg_2_payload= +msg_2_ciphertext=57d0d36040aea7cc919054c726a651796718f907af000923de50022aac735ff63edb6b8db36b3614c4a99a8f0439dd35a25669a26992d38212997d2e2b956544 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=078228238d9d65d53d9910156e32b61af70cac329a27000c3968d942f325af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=eaa3e5c640ca8998164b6fa6e2c3546393076d09e3f87493d20b91f3fbadd2 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a4e95d8a6ec9259c7fd75328ebf841c3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846667d638565845ccfec1044160484c0212 +msg_2_payload= +msg_2_ciphertext=83cbff8b883cab6302654c8d6d6e50a3e7323d9024018c648cf98824f0e880abb946e9e4e1a540c904ceae9d7fc3a3e23df2179a425d076051527f20bd5c157d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=62620d455bce603e36d0e324deb5ae87a2a3ac98b56a0de4b3cd02e98e285e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=37668ce320aa3b29cd5dd49bfc5fd63474ff03fade3bf0dde6164fa0030b64 + +handshake=Noise_XN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669bc42f905f6cea8c6d2152688b2db7a4a5e6bad2eb5e6bb6d67f +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=1ab983aef2af5558802d787fec340c612a9332b5ad54d9d76bea87516becc2394be6087d956d1e4a61de19f946b938e2d5ff457d78cb9ee139f9ce920104afac59a4bcdd664d58ab4463 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d195f8befc66baa201a18c4064909ebe8502e0f9b5e961314b61fd125d247d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86591937ccc7873fb61286c7d019e73daf8b40ec33dcc9d1fffe1c9a16dd4c + +handshake=Noise_XNpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254383b83be44ec842dd30040829f1859c3e6575f749244de0bf9df +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665933b46f951a73becfa39241e5fb3addacb4201d1c842fdc6574 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b1fa0b5e1310eb981ee2e54af06f5f88b5a9d0140be4b3bc6b2946a937e40d7fdafd771902eb11c326abd30b61887b86b9e89a78f9efa643f1cd8bf6e2fca221a8f95cd1b592d021fdb4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=553b9158015420d2b4692c4b30b0fb26ade7adfa1fcbcc182e90b7244054b3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2383835c704affed54b3525f4d7f63064538ce838cd706c9197aff8881fb31 + +handshake=Noise_XNpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447a625a9ed5dd10375d810bbf4dbff81da99b343d240f9c1992d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661977595c1b822311d2db413251d1961135b14cb2786f7a030b70 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8d7c08550caffdd7302901d1ef368326f22321a4511debccbbd532ccb7d96f28cd00b064a19fdb50dd2e68909f34604546fe0bfca84667d8681934aa1779b419c87ead0d4ef509d932ac +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=eb2dbb2a68310558e3a1ca71a2257cd6f28ddfd99fa854dc8011d812e90101 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=80c84ea17aa9f0d18602ab87eb20259a858074a95e5f076907e632667db5fb + +handshake=Noise_XNpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540dc8226f2f99fa7085cec3a3e87c17df7992d06de1d5c72dea3f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9fd0e03c736f0dbe8371d3f702aab8074e52ade0b150397a2cd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=57d0d36040aea7cc919054c726a651796718f907af000923de50022aac735ff670a9f1e667c41afe15ce41ee90c3a6d83214f3e01388aa3cd4913253f8982aa4c23b7af239ac6e88ce91 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=078228238d9d65d53d9910156e32b61af70cac329a27000c3968d942f325af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=eaa3e5c640ca8998164b6fa6e2c3546393076d09e3f87493d20b91f3fbadd2 + +handshake=Noise_XNpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546c1aa61ab88ff9a43d1ca8c9a354f488d3f1cd4c6f8efd232fd5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661588ca3f0797a06d1b636d50b498f7a84254af07424ed1b25094 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=83cbff8b883cab6302654c8d6d6e50a3e7323d9024018c648cf98824f0e880abf4c9c1c27f2965b5afe799f44cb4f89cd4d7fe0f1353b05c118a7017a7949d7f7851ece83e0bf5e9fb6f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=62620d455bce603e36d0e324deb5ae87a2a3ac98b56a0de4b3cd02e98e285e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=37668ce320aa3b29cd5dd49bfc5fd63474ff03fade3bf0dde6164fa0030b64 + +handshake=Noise_IN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9ab17086eb52ba02f54fe48b11cf7ae +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d4e08cc4a109b93413b9f2b93a90c3b52d328130346ae8a7a65693bbdfffb3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2bf0d845c35d0b63452e9477083d9c35feb7263cebf00828ce84fba88f94c0 + +handshake=Noise_INpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625405262b1f9b84cdb310908a65b2d6408f13ec9efef6a1b52c2bf0daaffe1e42204de45bf028283b88c60ab5cc2745b8e8c6cf4e30f5e4d01f7a36153c4d2028b1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fcf90b48cc4034aefda82a6593ca634e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d8f33663563115c594ca28b2fe01e8dae1cf498b312ceb4c18fc55a005cc6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36f1d5c7339b870e822497f1a014c1032e3268d62ea5bc7f80264b2de3535d + +handshake=Noise_INpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c205846663809a031f5a191bd9323566dc3c824c7273fa31a5fc1d54a8e951aa4f4a2c01331090fe2dc47358b134f4983e57f6e050a654d43575149488e4d962 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f9cecdffa97451986964e6b181e2961 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=79d1215e41ae753d5c8dafc474355e4b7af8ec2d84f13444f3d1c7bea75e53 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=216ecf739142ee4ce72573b4e79f765df31be2022377fee7e9847f558a6187 + +handshake=Noise_INpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541906307774eb6ae1a18c731b2af6d9bcf09b69e5b9b66678a3b968edb6550e7dc123f2506c770de516702097583503973ef95ff80d31b363f0e2637b8df344c7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ac222e4b2d2f6d105228f1f6eaab97ff +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f18b76b773ad92a0551eaaccac2822ef7c89e2e4141b493494a5671432e538 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b500b236900edd4ce3a74e0f021fc0b93bb677a8a0417996474ad1b3ad40f8 + +handshake=Noise_IN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466578e11ef9be6d820631037dc05abdcb236c57a2567ba93669ab0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d4e08cc4a109b93413b9f2b93a90c3b52d328130346ae8a7a65693bbdfffb3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2bf0d845c35d0b63452e9477083d9c35feb7263cebf00828ce84fba88f94c0 + +handshake=Noise_INpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625405262b1f9b84cdb310908a65b2d6408f13ec9efef6a1b52c2bf0daaffe1e42204de45bf028283b88c60ab5cc2745b8e87016ea492791838b92f00800e636883dc626eb2f3895011a139e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466217778ef3116b94146df592ed848106664bcbfff47169058bda2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d8f33663563115c594ca28b2fe01e8dae1cf498b312ceb4c18fc55a005cc6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36f1d5c7339b870e822497f1a014c1032e3268d62ea5bc7f80264b2de3535d + +handshake=Noise_INpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c205846663809a031f5a191bd9323566dc3c824c7273fa31a5fc1d54a8e951aa4f4a2c01331090fe2dc47358b134f4985722e0d190fada548c133472917187cdb527644e700547c52b28 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466471b4496207cea9199841fc64e1bb1b5b788be9d1689e4540867 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=79d1215e41ae753d5c8dafc474355e4b7af8ec2d84f13444f3d1c7bea75e53 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=216ecf739142ee4ce72573b4e79f765df31be2022377fee7e9847f558a6187 + +handshake=Noise_INpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541906307774eb6ae1a18c731b2af6d9bcf09b69e5b9b66678a3b968edb6550e7dc123f2506c770de516702097583503971cf56370e4abe94a9f67eda71c22f885de116aa378e1cd96eced +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846643ad2c9a96755f8efbbcf40b385fe808da55ab103c66dd8c1542 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f18b76b773ad92a0551eaaccac2822ef7c89e2e4141b493494a5671432e538 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b500b236900edd4ce3a74e0f021fc0b93bb677a8a0417996474ad1b3ad40f8 + +handshake=Noise_IN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846648988f7cb5d85b5c5c03e276b86fe50f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d4e08cc4a109b93413b9f2b93a90c3b52d328130346ae8a7a65693bbdfffb3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2bf0d845c35d0b63452e9477083d9c35feb7263cebf00828ce84fba88f94c0 + +handshake=Noise_INpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625405262b1f9b84cdb310908a65b2d6408f13ec9efef6a1b52c2bf0daaffe1e422032e60c283f594634358c6ade5821244600d8d2e6dea60137b4f10b074ba7193d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b1e5ecbcc832e6ac1a8414797bb920cb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d8f33663563115c594ca28b2fe01e8dae1cf498b312ceb4c18fc55a005cc6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36f1d5c7339b870e822497f1a014c1032e3268d62ea5bc7f80264b2de3535d + +handshake=Noise_INpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c205846663809a031f5a191bd9323566dc3c824c7273fa31a5fc1d54a8e951aa6ec025aad0d8f9cb26a27d5d1176d9a994077aab03b577f2e8039e4366bc6245 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d663e6ac3d33e23ad323622c476fe906 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=79d1215e41ae753d5c8dafc474355e4b7af8ec2d84f13444f3d1c7bea75e53 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=216ecf739142ee4ce72573b4e79f765df31be2022377fee7e9847f558a6187 + +handshake=Noise_INpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541906307774eb6ae1a18c731b2af6d9bcf09b69e5b9b66678a3b968edb6550e7dfee517c34ceeba54fee005b95e94e05103161169f40b807a26d7d3bf013b7f85 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664813a5e72f6b66ec89e411840f84ba80 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f18b76b773ad92a0551eaaccac2822ef7c89e2e4141b493494a5671432e538 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b500b236900edd4ce3a74e0f021fc0b93bb677a8a0417996474ad1b3ad40f8 + +handshake=Noise_IN_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466578e11ef9be6d82063107b23e9a7cdafd87a02d15059693b866a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d4e08cc4a109b93413b9f2b93a90c3b52d328130346ae8a7a65693bbdfffb3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2bf0d845c35d0b63452e9477083d9c35feb7263cebf00828ce84fba88f94c0 + +handshake=Noise_INpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625405262b1f9b84cdb310908a65b2d6408f13ec9efef6a1b52c2bf0daaffe1e422032e60c283f594634358c6ade582124467016ea492791838b92f08ea1ce07ac1c29aaca2ba2e6be8aae6f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466217778ef3116b94146df5f06a4a59dfcbb765ff9ffaf65d3063d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d8f33663563115c594ca28b2fe01e8dae1cf498b312ceb4c18fc55a005cc6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36f1d5c7339b870e822497f1a014c1032e3268d62ea5bc7f80264b2de3535d + +handshake=Noise_INpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c205846663809a031f5a191bd9323566dc3c824c7273fa31a5fc1d54a8e951aa6ec025aad0d8f9cb26a27d5d1176d9a95722e0d190fada548c13cebafccf5db40ddec9c8ee4edbf85e68 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466471b4496207cea9199840fb7d1bf618aa15eb0b74b90a0a8f9b4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=79d1215e41ae753d5c8dafc474355e4b7af8ec2d84f13444f3d1c7bea75e53 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=216ecf739142ee4ce72573b4e79f765df31be2022377fee7e9847f558a6187 + +handshake=Noise_INpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541906307774eb6ae1a18c731b2af6d9bcf09b69e5b9b66678a3b968edb6550e7dfee517c34ceeba54fee005b95e94e0511cf56370e4abe94a9f67f486bb56720c1832a61683a3ebde2eec +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846643ad2c9a96755f8efbbcab063bc3e701c9facb3668c1589ea2d6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f18b76b773ad92a0551eaaccac2822ef7c89e2e4141b493494a5671432e538 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b500b236900edd4ce3a74e0f021fc0b93bb677a8a0417996474ad1b3ad40f8 + +handshake=Noise_XK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543fba394be81d461ec599092e9a40c636 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a35be554752bb77f40ac980146ef9278 +msg_2_payload= +msg_2_ciphertext=5e88a8a22bc7df4d8b6c85eaa581a819ec04c6588a193d2af0de37da0e24a50f5b0d67595a3683f9866af793c510e046dc9c0208b821af4c16a9f2678739fc1e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e1b55532068a924fa7cd262612a53c9eb0b4925df7819a9afe61509d63a879 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94b7b8c259658fd03b54749fdd35464a286a6ba9cc9ff76833f20736f632db + +handshake=Noise_XKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254628f0972a8c6dffd9b1f6b0a9c692591 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846662111ca7ab008976bb43e298b4703b93 +msg_2_payload= +msg_2_ciphertext=b0582dab6c55505ee245bc3b96ea140a212c8fbc6d0c6a6dea3b66264af8080a9d84d415bacadb301ac578f87f03cc2a39d9f3a2d69b434c539916222b7571ba +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b21379d73f20b8effdf93a82f86a09520c92cd743a4323b1f048fad80e3ccf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=85a2892049d45dac297850412a71011489b13831bbc1eb3551361d1a81866b + +handshake=Noise_XKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254084e3679207acaf00c8676cf14887de0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663c5452c9722f395c25e4f50ed320d648 +msg_2_payload= +msg_2_ciphertext=5270bd250e9904a246463d7d975d9724fa0c1fca24e20f8cc19143e7f37ae1b6fdf66ce9da187377f6eac6601c773cc7a6e523730abc032a0739dffa836a2833 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3e92cd13d2b9922ccfff54653579cb0e8153c3adbe0ef016ff62c30e5aec77 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9c7f77109e64326d3c01369a3542137cfec0e8bb550fe4f16211a7d0d5aa47 + +handshake=Noise_XKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625460572f2e213e1bab8056917df9f342a9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e2cfb743b4c24761d3e753548ffcf885 +msg_2_payload= +msg_2_ciphertext=742c8b64404bd353aed4f94bd8608eaf78dc3be24690bf93956dac0021c8d510c830e3307d1325cfc6fe40abea2205adbc648ae8591fa6beb570b50ebf18dc30 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55d51d54c345abe9038b8b5b1032052740bee5daacb8812810eed8e1086c4c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=52f5cf6aa3f6c12c3d8333f70bfde158d17af6c68ab496010b6ac61d404a5c + +handshake=Noise_XKpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f3c24b47ca37d062ffa5a82d96a68807 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f7fa4fbea714e7bb8cde3e281568e80c +msg_2_payload= +msg_2_ciphertext=657cf68657783f22da2bc73c370cf967b4e5113479533ff00447e6e1e0d61c8ea86453b71ca934e88c911840807682451a674a5237f6a5c037d4500bdbbdf51b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5bb42f69e02b04f540695c05ec8af9ba7f8075e540d9a4721a72b900dda50 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57fe584b6806f892abc12e9876cb93f2dee7e798a2da2b40d18cedc51abde6 + +handshake=Noise_XK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548a7b8f977e8c05a05432685828169a203a60e39b9f2ae22a38bc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466816d6c440357f5acf5b0689176d7379fc88d59144d34dcc9cc43 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5e88a8a22bc7df4d8b6c85eaa581a819ec04c6588a193d2af0de37da0e24a50fc2e1d713b3c03faace1207f0a7cbd91d23e7d0c62d67c1eea84bb3c94fe9c525d4f7b8eb287df3fa5000 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e1b55532068a924fa7cd262612a53c9eb0b4925df7819a9afe61509d63a879 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94b7b8c259658fd03b54749fdd35464a286a6ba9cc9ff76833f20736f632db + +handshake=Noise_XKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625484c6d0554a6f76969dc0d53cda23f1a6a755b9966554422ea3d1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ad94991fe04bd330625d6e16d5591e3c47d0b024feb6e4faffe5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b0582dab6c55505ee245bc3b96ea140a212c8fbc6d0c6a6dea3b66264af8080ae490f4575fb9dfc85eb6a5a6bd873cb77d8ce8c82106d98c8f5218537ffbe88be703fccb23407f75eb97 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b21379d73f20b8effdf93a82f86a09520c92cd743a4323b1f048fad80e3ccf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=85a2892049d45dac297850412a71011489b13831bbc1eb3551361d1a81866b + +handshake=Noise_XKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c82ce3a8b803326d6ad5368ea48b1b880b3f85fb62587176c112 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466085d6eef93d49287bd6a6ae8bb1773d38bcd556e1cca019bfb56 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5270bd250e9904a246463d7d975d9724fa0c1fca24e20f8cc19143e7f37ae1b63f620a0e7bbaab400c6aff6549b4fe530636c9f422fd45b76bcfd99fa4fe05ad57bc2af01e4b1378342b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3e92cd13d2b9922ccfff54653579cb0e8153c3adbe0ef016ff62c30e5aec77 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9c7f77109e64326d3c01369a3542137cfec0e8bb550fe4f16211a7d0d5aa47 + +handshake=Noise_XKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f03a092dcf31be305b9897ffb1f6edf78c2308b7592e5ede5f8c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0c7547b9c1200bbf993ceaf07ee3e0ba1d21990c63c685bc2a6 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=742c8b64404bd353aed4f94bd8608eaf78dc3be24690bf93956dac0021c8d510c2f90f4e9157a1fb23a07e4ab218fbd2c0a6193184866cc4aa968cc9423ef3ed3cc4d3ee747f6db3d699 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55d51d54c345abe9038b8b5b1032052740bee5daacb8812810eed8e1086c4c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=52f5cf6aa3f6c12c3d8333f70bfde158d17af6c68ab496010b6ac61d404a5c + +handshake=Noise_XKpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549275659638adc4f810a217d9688cebda3ee76c41146fa6168000 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fad2e1206a13940ab0a339bb718fb50563add7e0f42ad5af3df2 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=657cf68657783f22da2bc73c370cf967b4e5113479533ff00447e6e1e0d61c8eac532982ce7784fe5b9fae18ee9f925bfc243ca41c6ddf6483a9126ea991130f96ead988170ae534d021 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5bb42f69e02b04f540695c05ec8af9ba7f8075e540d9a4721a72b900dda50 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57fe584b6806f892abc12e9876cb93f2dee7e798a2da2b40d18cedc51abde6 + +handshake=Noise_XK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625494382079878f98f580c3b1cbb5aa1b3e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669d6a740fa022b801a82f6d8f736a9221 +msg_2_payload= +msg_2_ciphertext=5e88a8a22bc7df4d8b6c85eaa581a819ec04c6588a193d2af0de37da0e24a50f3e9d35ee86621e9543a33614ab4c3cc9290c2266378883ed491d6b583fe98670 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e1b55532068a924fa7cd262612a53c9eb0b4925df7819a9afe61509d63a879 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94b7b8c259658fd03b54749fdd35464a286a6ba9cc9ff76833f20736f632db + +handshake=Noise_XKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254eac55cae26f24fb5d8f6d6ecd3030fe6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466071d80399439d99784391a3f08e6077c +msg_2_payload= +msg_2_ciphertext=b0582dab6c55505ee245bc3b96ea140a212c8fbc6d0c6a6dea3b66264af8080a7d55b3c0d87324d18eb0ee39b4ea01f13b6ad45ac612e2620433447bd81a2eaf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b21379d73f20b8effdf93a82f86a09520c92cd743a4323b1f048fad80e3ccf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=85a2892049d45dac297850412a71011489b13831bbc1eb3551361d1a81866b + +handshake=Noise_XKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d0ac9cf6374b5c793b64b5a9ffc7804 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466085a04d90bcc1a7539025325baf625d7 +msg_2_payload= +msg_2_ciphertext=5270bd250e9904a246463d7d975d9724fa0c1fca24e20f8cc19143e7f37ae1b64eb9bef8ea1419bcd7af3d017cc79d9f05407aeb86089e683f4a54a6eedee93f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3e92cd13d2b9922ccfff54653579cb0e8153c3adbe0ef016ff62c30e5aec77 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9c7f77109e64326d3c01369a3542137cfec0e8bb550fe4f16211a7d0d5aa47 + +handshake=Noise_XKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f5919b8e1ea6d8c820f3b1c6caf4b63f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f99ad158af497a66373342a7d9d6a334 +msg_2_payload= +msg_2_ciphertext=742c8b64404bd353aed4f94bd8608eaf78dc3be24690bf93956dac0021c8d510e1cba1d6ecb7d9b857bd55d75bf1dc283feda9825d97b4676885a73def70af6c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55d51d54c345abe9038b8b5b1032052740bee5daacb8812810eed8e1086c4c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=52f5cf6aa3f6c12c3d8333f70bfde158d17af6c68ab496010b6ac61d404a5c + +handshake=Noise_XKpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542519fd1f858e3a27f27f361b9dd33448 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1fee192dcc5bf08085d8b1630667a75 +msg_2_payload= +msg_2_ciphertext=657cf68657783f22da2bc73c370cf967b4e5113479533ff00447e6e1e0d61c8e90638cf47a9917c2d26d5e142f43e865b9923804b74a9431395b925c3692cb24 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5bb42f69e02b04f540695c05ec8af9ba7f8075e540d9a4721a72b900dda50 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57fe584b6806f892abc12e9876cb93f2dee7e798a2da2b40d18cedc51abde6 + +handshake=Noise_XK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548a7b8f977e8c05a05432384387977b5f322fefd1d838f7dbfb34 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466816d6c440357f5acf5b028b67758e280315cf45f994e4fe6554c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5e88a8a22bc7df4d8b6c85eaa581a819ec04c6588a193d2af0de37da0e24a50f8511d619d0aa5bddb2055dcab48f6b9023e7d0c62d67c1eea84b026b254bb79a8146b32f2f46c52b1e77 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e1b55532068a924fa7cd262612a53c9eb0b4925df7819a9afe61509d63a879 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94b7b8c259658fd03b54749fdd35464a286a6ba9cc9ff76833f20736f632db + +handshake=Noise_XKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625484c6d0554a6f76969dc069ea2dc2c034193fde8cac677ff7ae34 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ad94991fe04bd330625dff6616b01f49f3ed5e0a2473ead205e3 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b0582dab6c55505ee245bc3b96ea140a212c8fbc6d0c6a6dea3b66264af8080ac968116f28605c3eacb50d76624af7d07d8ce8c82106d98c8f52ba9db10cdb3d6865cd0b1c0e8eddec9d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b21379d73f20b8effdf93a82f86a09520c92cd743a4323b1f048fad80e3ccf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=85a2892049d45dac297850412a71011489b13831bbc1eb3551361d1a81866b + +handshake=Noise_XKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c82ce3a8b803326d6ad594b0b2bf72cd7c4995188e472049026b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466085d6eef93d49287bd6a7c369b1904dcfdc7c6e7d9357d9cfb86 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5270bd250e9904a246463d7d975d9724fa0c1fca24e20f8cc19143e7f37ae1b6362e57e3ca4cdc1a1dffa9673c33c5540636c9f422fd45b76bcf9d68cf255ebeb4a0dfdea896da2507aa +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3e92cd13d2b9922ccfff54653579cb0e8153c3adbe0ef016ff62c30e5aec77 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9c7f77109e64326d3c01369a3542137cfec0e8bb550fe4f16211a7d0d5aa47 + +handshake=Noise_XKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f03a092dcf31be305b98d6673fc3049849936cf71b2ba8ecd768 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0c7547b9c1200bbf9930021049e741e2109d9d17b27430a657f +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=742c8b64404bd353aed4f94bd8608eaf78dc3be24690bf93956dac0021c8d51068f966046fa835ceffab9f61156a0cb3c0a6193184866cc4aa96ee286092d40b1c200cb6a721ab5d5239 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55d51d54c345abe9038b8b5b1032052740bee5daacb8812810eed8e1086c4c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=52f5cf6aa3f6c12c3d8333f70bfde158d17af6c68ab496010b6ac61d404a5c + +handshake=Noise_XKpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549275659638adc4f810a22ecfa8d82eb64d6ba6dafa2ec5b48a85 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fad2e1206a13940ab0a3de71ac02f268e91fecdff42dc0f28930 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=657cf68657783f22da2bc73c370cf967b4e5113479533ff00447e6e1e0d61c8e5b2baf8950ce6c43c591dc1fc413e067fc243ca41c6ddf6483a965a1e55a1e106bac94c5f89d82405bed +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5bb42f69e02b04f540695c05ec8af9ba7f8075e540d9a4721a72b900dda50 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57fe584b6806f892abc12e9876cb93f2dee7e798a2da2b40d18cedc51abde6 + +handshake=Noise_IK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e4c987aee1def7f4451e94e52f2edcf3f88abd36f9a83613afec5cfba3d156ca3241a67c80714c7daf3a9695237fa6a4516a56c98ff0cb2136a1ecfa5987db0c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666e25d3e0f17564403749cb3472eec222 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=410d4ee9df61c268dddeee01e9035a81d099b7560f1d565624cddb19ccdea7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=29c70c4ff6224a7472bb3ef9a786470ec1982e798ba7f5b5c201e705652893 + +handshake=Noise_IKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b6d56750cabed6b4793bbd0a78c250ac5e2c53aa8df8fe0dbf15189011623c31add3ba342c9a3fb5240aa60aed3fd2994802c34a962c15dcd90edcb5102cf74 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669342a3df6cec558ad000387398eccccc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76071f1a7fb9d854f0e0395d7ad43deedbfbaa09b6ea187f565f6c009021ba +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49bde06081a37ef1bdf6670df3b2a2c3879505befdf77187d44f8f125f2d2e + +handshake=Noise_IKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625442c6abbd4f501864a318f49084d6edc465d6025bf9bfa58f08855e3924c965535125a8f083041204dad6d4fdbdf4c0a23088b534967aea9b6b9ec67ff60dee46 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663a536a2718f2256fb71d2b3e3e5ba163 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b723cbfbb75b3039c733be62919a5dc997419469b0a4efd0d12cb1937fb5df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=91532e9187412d8c91f8bf3064080b68d73bd677ed63ddfb60d7ac0ed6cc04 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254575510fd1ee7b381c333b77018908687c0a9aea3af69511201e97caa4a743e105d069f494432d8859fc610b81fed1f5e249dac1a2217ff72505457f145fda872 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cdbfa3b6cd68bdbc191a6441920da40d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c0a06e03b33924f95bede35f78563a6ec56fa623cc46cf09f55fc08ed8011d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d1f5f192af4b598d2e29afd9105617216708839d508f2073784a18a6a6fa6a + +handshake=Noise_IK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e4c987aee1def7f4451e94e52f2edcf3f88abd36f9a83613afec5cfba3d156ca3241a67c80714c7daf3a9695237fa6a466154654a805c143d8a92a12ba607ce52fa4921f215ec4b41789 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b54fb4d11ab95fa5013849718dfcbfb57b0aa6d423cc6b1e5c74 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=410d4ee9df61c268dddeee01e9035a81d099b7560f1d565624cddb19ccdea7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=29c70c4ff6224a7472bb3ef9a786470ec1982e798ba7f5b5c201e705652893 + +handshake=Noise_IKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b6d56750cabed6b4793bbd0a78c250ac5e2c53aa8df8fe0dbf15189011623c31add3ba342c9a3fb5240aa60aed3fd29aab66f9942bb0346812f1f380a6216514fc7f1ee5c4e064bbd26 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672547a8e33283d797b8c1a6219c6904161528f9da68ac5ab35db +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76071f1a7fb9d854f0e0395d7ad43deedbfbaa09b6ea187f565f6c009021ba +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49bde06081a37ef1bdf6670df3b2a2c3879505befdf77187d44f8f125f2d2e + +handshake=Noise_IKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625442c6abbd4f501864a318f49084d6edc465d6025bf9bfa58f08855e3924c965535125a8f083041204dad6d4fdbdf4c0a27282a568a006a2474d8305595ab4f5cf185f555b3369608e9f39 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846650bf4a2aba8abe046d9ddb3d73ca2c8754fea6c5fc5af7f07538 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b723cbfbb75b3039c733be62919a5dc997419469b0a4efd0d12cb1937fb5df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=91532e9187412d8c91f8bf3064080b68d73bd677ed63ddfb60d7ac0ed6cc04 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254575510fd1ee7b381c333b77018908687c0a9aea3af69511201e97caa4a743e105d069f494432d8859fc610b81fed1f5efc5c147038b683952ec2099209d2146ad862d95293ec3c38175d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d9312e9888b0b56ce23cb101090c86a3a7f5e0f4df15ee88b3ee +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c0a06e03b33924f95bede35f78563a6ec56fa623cc46cf09f55fc08ed8011d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d1f5f192af4b598d2e29afd9105617216708839d508f2073784a18a6a6fa6a + +handshake=Noise_IK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e4c987aee1def7f4451e94e52f2edcf3f88abd36f9a83613afec5cfba3d156ca23c0cff39fe89439ce3a8aa083ba16fb93ea47b2f5e9b5b64b91f53e6c3cdf12 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846604e05abd3e92d415e1b7c232d6e91964 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=410d4ee9df61c268dddeee01e9035a81d099b7560f1d565624cddb19ccdea7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=29c70c4ff6224a7472bb3ef9a786470ec1982e798ba7f5b5c201e705652893 + +handshake=Noise_IKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b6d56750cabed6b4793bbd0a78c250ac5e2c53aa8df8fe0dbf15189011623c31c03513c168584cbece10798ab45fc2ac41aacfc87f02840a8e1df005b094a9b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466642b389be08a294dcb65f508382fac63 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76071f1a7fb9d854f0e0395d7ad43deedbfbaa09b6ea187f565f6c009021ba +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49bde06081a37ef1bdf6670df3b2a2c3879505befdf77187d44f8f125f2d2e + +handshake=Noise_IKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625442c6abbd4f501864a318f49084d6edc465d6025bf9bfa58f08855e3924c965531dcb0438a43fefd352e9e6a79b98bd1b2c476b239cbe1cbcbbb5ddfa78064e40 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692389a661fad3c014072134790eeeff6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b723cbfbb75b3039c733be62919a5dc997419469b0a4efd0d12cb1937fb5df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=91532e9187412d8c91f8bf3064080b68d73bd677ed63ddfb60d7ac0ed6cc04 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254575510fd1ee7b381c333b77018908687c0a9aea3af69511201e97caa4a743e103248ca4db0040cfd5fdc65d4dcf88051c39cb96747255580863f7a34c7bc56f7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ed376bd9b78fd69ba3b5a38d84c93fd1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c0a06e03b33924f95bede35f78563a6ec56fa623cc46cf09f55fc08ed8011d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d1f5f192af4b598d2e29afd9105617216708839d508f2073784a18a6a6fa6a + +handshake=Noise_IK_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e4c987aee1def7f4451e94e52f2edcf3f88abd36f9a83613afec5cfba3d156ca23c0cff39fe89439ce3a8aa083ba16fb66154654a805c143d8a926195b37d8d08a4fcdefff201de9f069 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b54fb4d11ab95fa50138358319a81593d62664ca0ad72f63c8d5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=410d4ee9df61c268dddeee01e9035a81d099b7560f1d565624cddb19ccdea7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=29c70c4ff6224a7472bb3ef9a786470ec1982e798ba7f5b5c201e705652893 + +handshake=Noise_IKpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b6d56750cabed6b4793bbd0a78c250ac5e2c53aa8df8fe0dbf15189011623c31c03513c168584cbece10798ab45fc2aaab66f9942bb0346812f14630b559db512874d6eca353bdb7135 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672547a8e33283d797b8c646ae93be9f51723c08fc117b388c36c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76071f1a7fb9d854f0e0395d7ad43deedbfbaa09b6ea187f565f6c009021ba +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49bde06081a37ef1bdf6670df3b2a2c3879505befdf77187d44f8f125f2d2e + +handshake=Noise_IKpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625442c6abbd4f501864a318f49084d6edc465d6025bf9bfa58f08855e3924c965531dcb0438a43fefd352e9e6a79b98bd1b7282a568a006a2474d83f1e95944af542ae2a5c246afa7b1242a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846650bf4a2aba8abe046d9d847c49963b2b21211eb16f5bb7b42cf9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b723cbfbb75b3039c733be62919a5dc997419469b0a4efd0d12cb1937fb5df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=91532e9187412d8c91f8bf3064080b68d73bd677ed63ddfb60d7ac0ed6cc04 + +handshake=Noise_IKpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254575510fd1ee7b381c333b77018908687c0a9aea3af69511201e97caa4a743e103248ca4db0040cfd5fdc65d4dcf88051fc5c147038b683952ec2a1de96b1f5804dc4dd69ce7bbe8de7ab +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d9312e9888b0b56ce23cedf9537317b8b0121d90405c3e5e89df +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c0a06e03b33924f95bede35f78563a6ec56fa623cc46cf09f55fc08ed8011d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d1f5f192af4b598d2e29afd9105617216708839d508f2073784a18a6a6fa6a + +handshake=Noise_XX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466881a9849f98286c79700c48c40e6667ce14ce8baabdf27b51fb80d248c2d56a65be777dc2ad2438d794410a91e1542a138b33b73a5ff808ecff2e90952defca9 +msg_2_payload= +msg_2_ciphertext=a0c7c991f077df03c26762bb80c9dc4c830c71a012dc1a002363a684c659a3487c8a7c790075c7a5ac8de6fe1ccc7363d39bea6035a91323f511f662ee40d9de +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d52095f5c41973904a84746d988f0e424ec0832c3257cb4675eab76c4c197f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e1a5d80c71d13bde2e6b2559ecc953b97939de528e1ae166a64540265918 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625494973748946c53f4c3f0db3c62e50099 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466289a21b67ebcd303874b2b58d5ad4c6aa597823a9fdb77f2a5206bd199cefd0afa1402a0672f9df8bbbe4c6dc9e40fee220c5650cf918735768cbb4d0304bace +msg_2_payload= +msg_2_ciphertext=72e8d243ded18bf346c63e43042561f1f7eea7d61e499ba2e51f6819a5c556ce2a5e04c824b6c100e0a798bba881e39592214a04d798571575590d2490a76084 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c8c6894b90eb696c12292043bbb40f9a328aa548a3d0a3f71ef025a9b504f2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb30fc91a2a3fe04b50793a90835418f73173af49782a9655469ef389b0f8b + +handshake=Noise_XXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625477ffea436edf0c2502c18ab6c5ea925c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661bb41bc44a3c6bf571d96d127cc540711c9d29c6b5225a7ca69f1a8eba6ba143c76b96f3a32b34d0a54da910155fb59ca7e36e03928fb6b456c7a0a6d8cd6bcc +msg_2_payload= +msg_2_ciphertext=68bbb40ac1a9fa5f73a62c7619412ceeef08851e539edae876d22a77589b714b29fc73ebc63fd53703760dfb5b113f810304b5bb64f002f0b9c005f5109bf09b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b80aad9eee02c2105326ce8b8742f79c648df188075c60ce036070737da384 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a90ba8d19bd5fcac4dab5203f7ad6311a0b2ba489b05dbe7718d06a0fbc001 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b142f929c44494d1a0458dcce84eb647 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667e309552812f7796950972a8683660efcd19841b13a0f8b4e73ff2283d4240da0f3bc5a07c22a22b596eff3de2e5f32ffd0a5573ecd32dddd5996bfa5dcf6cb5 +msg_2_payload= +msg_2_ciphertext=42f39db26ff8d341399e35badb4d01392349af4a4d9ccc8fa34dedf38bb22fa0dc88a7767b9a4fa2ed8c03164ddad3762f658cd9af264c06ba838caee5b5924c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5b7e08b5f8473fcfb9ea1d921aca681d220045c2c99c052067cab897f57a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=68f4d64bdc52e4db8618374df2693239e2abfb769adce30ba36709ce94b09d + +handshake=Noise_XXpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548eb7890b9ae7c832d44eb674f849b235 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663a5c4a9bed2e487576db434ac38ce4e27e65e3aa233acd74dd5ff515a90ce1ed94189db4ce2e6ab986fa649ad0ce12cc986cba0a6f543f5781327884b9160eec +msg_2_payload= +msg_2_ciphertext=5c234f66a0c1f8603e407c1aa7d44a6121e170b15a28d903e58fbe52d03111690e20f382d3b0a221cadcb887ec014029a54bcf1904980c34b4a3b23194ca4860 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15d59f30f156bfa9065631ed3cb2342e82fb2cf850e0ed2a37b5d21caacce3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=252a53c772510b5322ed3ff20b30d1e3d2d370e6684bf640201ad04b613b02 + +handshake=Noise_XX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466881a9849f98286c79700c48c40e6667ce14ce8baabdf27b51fb80d248c2d56a6d35f521ebb5ab02d7db36ad16024c4f73cf130e8e1cb1b62a54aae4524ddefdb92d2eb92b80c99d9dff8 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a0c7c991f077df03c26762bb80c9dc4c830c71a012dc1a002363a684c659a3483672cd61275f36c652ad0226320581534b172fee0f1c41b654c5884d78edc65fda9770c1ba6e96ffd7ff +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d52095f5c41973904a84746d988f0e424ec0832c3257cb4675eab76c4c197f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e1a5d80c71d13bde2e6b2559ecc953b97939de528e1ae166a64540265918 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548481c4600f085d1c599bb7c9826aa10f1b0d6ff4167bb1824989 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466289a21b67ebcd303874b2b58d5ad4c6aa597823a9fdb77f2a5206bd199cefd0ab2d2062f3146f66ddc482f2f08dcae5c42dbd90643a806d4efd3565e01a0441cd9d8711b2e53f6328308 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=72e8d243ded18bf346c63e43042561f1f7eea7d61e499ba2e51f6819a5c556ce815d16cb6e27ec20aedeedcba498f2be70fa8af7396bc363498528a37b435784f4802d9ffa89f8f4149a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c8c6894b90eb696c12292043bbb40f9a328aa548a3d0a3f71ef025a9b504f2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb30fc91a2a3fe04b50793a90835418f73173af49782a9655469ef389b0f8b + +handshake=Noise_XXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542c0b0e441f5fa603216153e4aec070f29385fdeda4a5a812f1ba +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661bb41bc44a3c6bf571d96d127cc540711c9d29c6b5225a7ca69f1a8eba6ba1433eb446aea3823040decee92311318e59e89c2ba5f9c3bb8bae87f18ad6a2cbc3385f74e2908927bfa971 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=68bbb40ac1a9fa5f73a62c7619412ceeef08851e539edae876d22a77589b714b37b451c385c4004eeb865c67ea744f95bd6dddfc711abc8dd6d43636752808a6aa598904665ea8adc38c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b80aad9eee02c2105326ce8b8742f79c648df188075c60ce036070737da384 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a90ba8d19bd5fcac4dab5203f7ad6311a0b2ba489b05dbe7718d06a0fbc001 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aaf69bdfb1097bc7ef7434c8f6b361d3c56765dfc22ff727fda7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667e309552812f7796950972a8683660efcd19841b13a0f8b4e73ff2283d4240da30a2370fbbb64cc5290c58f4b1384bfb236d208257a60fdea450b3fa9a436f78914a07c1556ed6ee1626 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=42f39db26ff8d341399e35badb4d01392349af4a4d9ccc8fa34dedf38bb22fa045dab2ec12ba7a2c3648f1f3b838659f7ff333033cc7d08e83621a3c06ba34a810cb6f196149579160b1 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5b7e08b5f8473fcfb9ea1d921aca681d220045c2c99c052067cab897f57a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=68f4d64bdc52e4db8618374df2693239e2abfb769adce30ba36709ce94b09d + +handshake=Noise_XXpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a7c911d94ce4484b53ba5071c24ac9bc5450ae8c596d0f81b28f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663a5c4a9bed2e487576db434ac38ce4e27e65e3aa233acd74dd5ff515a90ce1ed7c9313a3a276333eec17fbd506ae3517e58f3e80b076f721352751eb6389ba9c629325042ede03308001 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5c234f66a0c1f8603e407c1aa7d44a6121e170b15a28d903e58fbe52d03111691892f24cc3ab41fc4cc57e270fc4dc61d449cc67794d27fa94cbafc9d3144cbda3f0099a09043f63a0df +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15d59f30f156bfa9065631ed3cb2342e82fb2cf850e0ed2a37b5d21caacce3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=252a53c772510b5322ed3ff20b30d1e3d2d370e6684bf640201ad04b613b02 + +handshake=Noise_XX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466881a9849f98286c79700c48c40e6667ce14ce8baabdf27b51fb80d248c2d56a603c1a5efe2c15f405d2aff0296f0dbcf6069f8aca95b8c7a930fb910d8032f87 +msg_2_payload= +msg_2_ciphertext=a0c7c991f077df03c26762bb80c9dc4c830c71a012dc1a002363a684c659a348ee08e3a592efd47624fd916ad05e0240000f553c46da776c0323202e72efebf2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d52095f5c41973904a84746d988f0e424ec0832c3257cb4675eab76c4c197f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e1a5d80c71d13bde2e6b2559ecc953b97939de528e1ae166a64540265918 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549b618e6f51bc8446b0ddfcbec9b3734a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466289a21b67ebcd303874b2b58d5ad4c6aa597823a9fdb77f2a5206bd199cefd0ac4e0efeeeae405223369ce0be060b3aaf167673c34a317c406380ae734fe4b1f +msg_2_payload= +msg_2_ciphertext=72e8d243ded18bf346c63e43042561f1f7eea7d61e499ba2e51f6819a5c556ce6ffa24ddbaa0238ab82e992c850c29e8b51d12483c258a10b9bb026c8a801247 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c8c6894b90eb696c12292043bbb40f9a328aa548a3d0a3f71ef025a9b504f2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb30fc91a2a3fe04b50793a90835418f73173af49782a9655469ef389b0f8b + +handshake=Noise_XXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ab765d8d10260f702bba6591780b98dc +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661bb41bc44a3c6bf571d96d127cc540711c9d29c6b5225a7ca69f1a8eba6ba143cd1aca7fb41b0ddd8031a718b144492ce2f62f7d6ef980460e65216c20f9c7e7 +msg_2_payload= +msg_2_ciphertext=68bbb40ac1a9fa5f73a62c7619412ceeef08851e539edae876d22a77589b714b82eccf7bc87129c069f11a8cc539a147bc1efeccfa736f370deef88a0acc8784 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b80aad9eee02c2105326ce8b8742f79c648df188075c60ce036070737da384 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a90ba8d19bd5fcac4dab5203f7ad6311a0b2ba489b05dbe7718d06a0fbc001 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ff7a4d153ade1ea6e96c452a20a8e3bc +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667e309552812f7796950972a8683660efcd19841b13a0f8b4e73ff2283d4240dac7bb45f67bb45b70fb4d2ebb27cc04b6ee40c5754c3a4f2692e05c045968574b +msg_2_payload= +msg_2_ciphertext=42f39db26ff8d341399e35badb4d01392349af4a4d9ccc8fa34dedf38bb22fa05e4d9f9a35ea24dccc479fbc9e2a65efcb4872b86cd77d8422fdfa7ee43a052e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5b7e08b5f8473fcfb9ea1d921aca681d220045c2c99c052067cab897f57a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=68f4d64bdc52e4db8618374df2693239e2abfb769adce30ba36709ce94b09d + +handshake=Noise_XXpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625453a789a04c5ca870fc4e845827e25976 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663a5c4a9bed2e487576db434ac38ce4e27e65e3aa233acd74dd5ff515a90ce1ed33f7a9ba95b680aabfdcd6faf180864ccfa6e32cf5dd2015069240ad2bde63dc +msg_2_payload= +msg_2_ciphertext=5c234f66a0c1f8603e407c1aa7d44a6121e170b15a28d903e58fbe52d031116938bd08876647a8f9b53897ba3b993bc00824f3e9ad26f887175203ddd58e400e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15d59f30f156bfa9065631ed3cb2342e82fb2cf850e0ed2a37b5d21caacce3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=252a53c772510b5322ed3ff20b30d1e3d2d370e6684bf640201ad04b613b02 + +handshake=Noise_XX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466881a9849f98286c79700c48c40e6667ce14ce8baabdf27b51fb80d248c2d56a6760edec0b63677b285a157e0c68bd18f3cf130e8e1cb1b62a54aec0aa715200fa9e0095e353bd5cc6c99 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a0c7c991f077df03c26762bb80c9dc4c830c71a012dc1a002363a684c659a348806b2304b1b50e1273f35f0e9c1fb86b4b172fee0f1c41b654c5ea91e10467f8911bcd6ff4fd0df18794 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d52095f5c41973904a84746d988f0e424ec0832c3257cb4675eab76c4c197f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e1a5d80c71d13bde2e6b2559ecc953b97939de528e1ae166a64540265918 + +handshake=Noise_XXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548481c4600f085d1c599b05cb00d2513b8084b6169bfc5bb7c585 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466289a21b67ebcd303874b2b58d5ad4c6aa597823a9fdb77f2a5206bd199cefd0a6b7ae867af93fabe3076dd8e7e0eb2d342dbd90643a806d4efd3cd2e89fa996d73ad84120ea05d413ad7 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=72e8d243ded18bf346c63e43042561f1f7eea7d61e499ba2e51f6819a5c556ced607e93b2dfaa12a116a8ed4abdfde1370fa8af7396bc36349858ddaaf9086bf4bbc1bbaf725de27b117 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c8c6894b90eb696c12292043bbb40f9a328aa548a3d0a3f71ef025a9b504f2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=fb30fc91a2a3fe04b50793a90835418f73173af49782a9655469ef389b0f8b + +handshake=Noise_XXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542c0b0e441f5fa60321617cd5aaa5126df6112f9fd7d4a4060d0f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661bb41bc44a3c6bf571d96d127cc540711c9d29c6b5225a7ca69f1a8eba6ba143c81802b4196029f4dd49cda7a9667171e89c2ba5f9c3bb8bae87d62743fbd6c41b29b90e28abe5c53789 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=68bbb40ac1a9fa5f73a62c7619412ceeef08851e539edae876d22a77589b714b64215da6697d5de8b5859e3a18fa350cbd6dddfc711abc8dd6d44805dd2117144b1abdcbfa863f2724c6 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b80aad9eee02c2105326ce8b8742f79c648df188075c60ce036070737da384 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a90ba8d19bd5fcac4dab5203f7ad6311a0b2ba489b05dbe7718d06a0fbc001 + +handshake=Noise_XXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aaf69bdfb1097bc7ef744544458a0e3b93b54da858c0219c4f9c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667e309552812f7796950972a8683660efcd19841b13a0f8b4e73ff2283d4240da4aad79ffed55b9f1d7e9257f49e341c6236d208257a60fdea4509d21ea64a04dae01a87b8fc3c7c564aa +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=42f39db26ff8d341399e35badb4d01392349af4a4d9ccc8fa34dedf38bb22fa06e9d56dd6bee77cbb228ac33eac073e67ff333033cc7d08e836232bfc71b12fed59ee9c98d159775d03e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5b7e08b5f8473fcfb9ea1d921aca681d220045c2c99c052067cab897f57a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=68f4d64bdc52e4db8618374df2693239e2abfb769adce30ba36709ce94b09d + +handshake=Noise_XXpsk3_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a7c911d94ce4484b53ba1d3eb5d88b66cf8083a3af2f7cbe4ef7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663a5c4a9bed2e487576db434ac38ce4e27e65e3aa233acd74dd5ff515a90ce1edb208e022f907532a068c7498e0aaea01e58f3e80b076f721352785c23cf88eb4fff0dce143e9eea6735b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5c234f66a0c1f8603e407c1aa7d44a6121e170b15a28d903e58fbe52d031116999fbc2a23fe6dd1a2e8347383b1add8bd449cc67794d27fa94cb501bb6b0dcf7e6704b3f454f28b7ca74 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15d59f30f156bfa9065631ed3cb2342e82fb2cf850e0ed2a37b5d21caacce3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=252a53c772510b5322ed3ff20b30d1e3d2d370e6684bf640201ad04b613b02 + +handshake=Noise_IX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1ce2a834dd79601d96e93cd87f9cb5ab910a94dc1c3aff65cc8a8bbfaa3f92d5f27af354133ca719324555c65ffd2c1d2e472871b0412ac82c4816c798656cc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9466b89d06e6480bd641be5427af829d10cb3587147334a8cb22d12be0a8c0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=988653bd8c786f07f5fd3978d4b4c2ef5fcc54e922bdc51a3bfebf88775773 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e17609d47e41aefd58600f2429a4079e30bc7c7a54960092f478e3a8b2ac897e5d02f331ca4f071810c4400747db69f287bb7bd2613b9bb9696f1d0332ffb49f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665b8c37f4b30ec0d0e7bd2c2df58f36c5c07cf55d88f33c1f25e4a7028d4ebf27e6499b388d97612d0d8e3d843613fcc10c85952bdb9f6ff4e6224a6673acf072 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d897592021d2ac4f4d5806105f48371c29282a6a72ec4f5774248ffa172dab +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=53c1f9f52e81ed46781adf8ea6bdd05c62b6e4f504cea15bacb669e4c41cde + +handshake=Noise_IXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e0e42ae7efaf198ba4628458bbd2824d836e24f1c558674ce8a6718178a8df958bff6c92b1f83c27b67e9c635956e1e37e2949990529f155b14bbd460b2c8207 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846664ad11b977ffd27f6732871a81fdea7702e2867e4953a6268ef1ac334632de746ac9811a6548b94151edf998a1c6f8a42f28cc714bc91e0baf43948a61acaf54 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4933a12a52fcc1e5088e9cc6811d542e3a8bafd64b821795fed855c8c07d98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fb9d7a40d84a9f6e1cbf0a74b327d0ce75b191ad37cb6a333730e196a2b95d + +handshake=Noise_IXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547ef2ddaa7167ce00a9dae6705805e8745f6dcbfc15a0fdb870a2a1d5a2248ccb625ad8a5a599f93caf0cb7c9108cb22aa3d483270bc7b0049b0a04a352df3999 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846642fbf7969708ccb5848f5e2c10ad358337b3581e939885f51562ea7973968931934c8bb5c7a2fe76a9afff12ef17bf773abfb17d03ba3f70b59672de1948cda8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7ccfa4fa03625064a116414a6ee0409c6d6c0f5398fb68aef65e271d8efad9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=571d9e1c4ff1f12c8cfbdfecb1d040d0dc86a41ab6efff8af515db514a2120 + +handshake=Noise_IX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1ce2a834dd79601d96e93cd87f9cb5ab910a94dc1c3aff65cc8a8bbfaa3f92d13220a1c98e2da8ff11520cdaf69c8edb270e4f47968b021af7801dd1a7ea41817d4107a6784b31d7a25 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9466b89d06e6480bd641be5427af829d10cb3587147334a8cb22d12be0a8c0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=988653bd8c786f07f5fd3978d4b4c2ef5fcc54e922bdc51a3bfebf88775773 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e17609d47e41aefd58600f2429a4079e30bc7c7a54960092f478e3a8b2ac897e5d02f331ca4f071810c4400747db69f2a960f5fe61a3d4eb096bda1618b89957324fa42142a4479e58d8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665b8c37f4b30ec0d0e7bd2c2df58f36c5c07cf55d88f33c1f25e4a7028d4ebf27d47ef437c44564d6b9824c813474b23c75ec7a42f32f740ddeb7cb029e46da19400b0548da6fa9d33040 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d897592021d2ac4f4d5806105f48371c29282a6a72ec4f5774248ffa172dab +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=53c1f9f52e81ed46781adf8ea6bdd05c62b6e4f504cea15bacb669e4c41cde + +handshake=Noise_IXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e0e42ae7efaf198ba4628458bbd2824d836e24f1c558674ce8a6718178a8df958bff6c92b1f83c27b67e9c635956e1e3ea0ae732463351778665fb6c549220bda51ca4dab499127b2e90 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846664ad11b977ffd27f6732871a81fdea7702e2867e4953a6268ef1ac334632de742025999d290bfb83d5e00b52aeca7dcd506a082856b65911e0cc85a7d923d2285550161acb482e4ee0d1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4933a12a52fcc1e5088e9cc6811d542e3a8bafd64b821795fed855c8c07d98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fb9d7a40d84a9f6e1cbf0a74b327d0ce75b191ad37cb6a333730e196a2b95d + +handshake=Noise_IXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547ef2ddaa7167ce00a9dae6705805e8745f6dcbfc15a0fdb870a2a1d5a2248ccb625ad8a5a599f93caf0cb7c9108cb22ac70f73b4d75fe9d0d019cab3ef8980a988842f9351e17a45d19b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846642fbf7969708ccb5848f5e2c10ad358337b3581e939885f51562ea797396893193f4a2cd2f7319f95f91545a426303b6f353dc9027ccba95e44993f61a51cf71b82a4af7d8f51471419f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7ccfa4fa03625064a116414a6ee0409c6d6c0f5398fb68aef65e271d8efad9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=571d9e1c4ff1f12c8cfbdfecb1d040d0dc86a41ab6efff8af515db514a2120 + +handshake=Noise_IX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1ce2a834dd79601d96e93cd87f9cb5ab910a94dc1c3aff65cc8a8bbfaa3f92d3ee79db4b8ef12dff465ece323fd782781b410bdbe128fac6ed4aafa2e5d1036 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9466b89d06e6480bd641be5427af829d10cb3587147334a8cb22d12be0a8c0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=988653bd8c786f07f5fd3978d4b4c2ef5fcc54e922bdc51a3bfebf88775773 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e17609d47e41aefd58600f2429a4079e30bc7c7a54960092f478e3a8b2ac897e0f793c7eca1b142371f5c7adcd39ef2d85d2cc45261b4c844d26a700b8080a71 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665b8c37f4b30ec0d0e7bd2c2df58f36c5c07cf55d88f33c1f25e4a7028d4ebf27f63b0c7c9fc405892f9a45dbb3136db02e186f41f5852fcb61148c13c2faaf05 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d897592021d2ac4f4d5806105f48371c29282a6a72ec4f5774248ffa172dab +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=53c1f9f52e81ed46781adf8ea6bdd05c62b6e4f504cea15bacb669e4c41cde + +handshake=Noise_IXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e0e42ae7efaf198ba4628458bbd2824d836e24f1c558674ce8a6718178a8df95a92bf930313b0c166e327b6df9e230fd99f3adef07e10e98d8a6cc5cfcdcefd2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846664ad11b977ffd27f6732871a81fdea7702e2867e4953a6268ef1ac334632de74f47e0a7d1f82839c24edf89e23718f37aa90feb7e4b0172a8c7efff3c9950443 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4933a12a52fcc1e5088e9cc6811d542e3a8bafd64b821795fed855c8c07d98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fb9d7a40d84a9f6e1cbf0a74b327d0ce75b191ad37cb6a333730e196a2b95d + +handshake=Noise_IXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547ef2ddaa7167ce00a9dae6705805e8745f6dcbfc15a0fdb870a2a1d5a2248ccb39325f84a4fef594c2b2505ed80a82f52d378b7ebd94fca5ed054c5d4b25e62f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846642fbf7969708ccb5848f5e2c10ad358337b3581e939885f51562ea7973968931420324746210e7aba862fcae3756f99d879260a2abc0e93d159e764c3945cf3b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7ccfa4fa03625064a116414a6ee0409c6d6c0f5398fb68aef65e271d8efad9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=571d9e1c4ff1f12c8cfbdfecb1d040d0dc86a41ab6efff8af515db514a2120 + +handshake=Noise_IX_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1ce2a834dd79601d96e93cd87f9cb5ab910a94dc1c3aff65cc8a8bbfaa3f92d75c33e2c9a58e7a754fa198b475f15a1b270e4f47968b021af78afd7c7783d1c26ef47324aa3e92a9b2a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9466b89d06e6480bd641be5427af829d10cb3587147334a8cb22d12be0a8c0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=988653bd8c786f07f5fd3978d4b4c2ef5fcc54e922bdc51a3bfebf88775773 + +handshake=Noise_IXpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e17609d47e41aefd58600f2429a4079e30bc7c7a54960092f478e3a8b2ac897e0f793c7eca1b142371f5c7adcd39ef2da960f5fe61a3d4eb096b2d9222aa6220a4baede9117fd8b82f70 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665b8c37f4b30ec0d0e7bd2c2df58f36c5c07cf55d88f33c1f25e4a7028d4ebf273fa04865b7cd6c2c521234163b0cf18975ec7a42f32f740ddeb7bcabc5810784ac068eaf9430c51a17f7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d897592021d2ac4f4d5806105f48371c29282a6a72ec4f5774248ffa172dab +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=53c1f9f52e81ed46781adf8ea6bdd05c62b6e4f504cea15bacb669e4c41cde + +handshake=Noise_IXpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e0e42ae7efaf198ba4628458bbd2824d836e24f1c558674ce8a6718178a8df95a92bf930313b0c166e327b6df9e230fdea0ae732463351778665999485bd22d3214b8adf6b4789850649 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846664ad11b977ffd27f6732871a81fdea7702e2867e4953a6268ef1ac334632de74804554e9834e401fd69f2fe7a4a65824506a082856b65911e0cc771287e7443e22c12bc684a7d034728b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4933a12a52fcc1e5088e9cc6811d542e3a8bafd64b821795fed855c8c07d98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fb9d7a40d84a9f6e1cbf0a74b327d0ce75b191ad37cb6a333730e196a2b95d + +handshake=Noise_IXpsk2_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547ef2ddaa7167ce00a9dae6705805e8745f6dcbfc15a0fdb870a2a1d5a2248ccb39325f84a4fef594c2b2505ed80a82f5c70f73b4d75fe9d0d0195324b867f091e0873e8ce23e989739f5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846642fbf7969708ccb5848f5e2c10ad358337b3581e939885f51562ea797396893112d7906e33b4b68026c9dd8783d6f307f353dc9027ccba95e449ab7b3308c2a2f866863cad318e811cb6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7ccfa4fa03625064a116414a6ee0409c6d6c0f5398fb68aef65e271d8efad9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=571d9e1c4ff1f12c8cfbdfecb1d040d0dc86a41ab6efff8af515db514a2120 + +handshake=Noise_N_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a69eac07dc78694d6a30a4c7f2120bc4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=53dc944be58d1292365d6a5096b1d990353d826dd51e0cfeef9820d480d814 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0ac777bf15a2f8e9ae4c0fd7d53aa4b6b61cbb33ea1e64f726aa51cb6c3b57 + +handshake=Noise_Npsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548ee4ea4ef70d80e3be3383136c01dba7 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7b2521d4d92735ed21e8ef9b635353c6cbbe6ba708e234d8d30c593af6091c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5a66f48e7581384a50a8a6197a76a21fe6e109f3b3c9c89cd335845970a875 + +handshake=Noise_Npsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254341b1bfc14a6369937b021c81f3b19a0 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f2a1148bdbfaf3843292d3ad1d665cb11a83f1a412c3f9c04f6b876a91ff00 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=caa8b41e1b5d2289d4f8e91ee4587dbc6335873e1a9b1f9f4a220d3cbbdd2d + +handshake=Noise_N_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254059099a62768f40676c0696be1c8076e4620fb27faad0ae8abb2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=53dc944be58d1292365d6a5096b1d990353d826dd51e0cfeef9820d480d814 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0ac777bf15a2f8e9ae4c0fd7d53aa4b6b61cbb33ea1e64f726aa51cb6c3b57 + +handshake=Noise_Npsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cff66e55f9165514342e82b98a436b78c1172bd9a5d44538c499 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7b2521d4d92735ed21e8ef9b635353c6cbbe6ba708e234d8d30c593af6091c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5a66f48e7581384a50a8a6197a76a21fe6e109f3b3c9c89cd335845970a875 + +handshake=Noise_Npsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542bf8c34c79ce1dd4da49f8ed9dfdbbe608500f4aeb3610f2ebf5 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f2a1148bdbfaf3843292d3ad1d665cb11a83f1a412c3f9c04f6b876a91ff00 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=caa8b41e1b5d2289d4f8e91ee4587dbc6335873e1a9b1f9f4a220d3cbbdd2d + +handshake=Noise_N_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c927ef8c933450ef29c8fe116405cad6 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=53dc944be58d1292365d6a5096b1d990353d826dd51e0cfeef9820d480d814 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0ac777bf15a2f8e9ae4c0fd7d53aa4b6b61cbb33ea1e64f726aa51cb6c3b57 + +handshake=Noise_Npsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fba424bfce5fb315d8c4452c719600d4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7b2521d4d92735ed21e8ef9b635353c6cbbe6ba708e234d8d30c593af6091c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5a66f48e7581384a50a8a6197a76a21fe6e109f3b3c9c89cd335845970a875 + +handshake=Noise_Npsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e88eae4b737047e2ebd9a57e4179dee4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f2a1148bdbfaf3843292d3ad1d665cb11a83f1a412c3f9c04f6b876a91ff00 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=caa8b41e1b5d2289d4f8e91ee4587dbc6335873e1a9b1f9f4a220d3cbbdd2d + +handshake=Noise_N_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254059099a62768f40676c0ad747e00bc4abdc4e547b5d64a203faa +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=53dc944be58d1292365d6a5096b1d990353d826dd51e0cfeef9820d480d814 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0ac777bf15a2f8e9ae4c0fd7d53aa4b6b61cbb33ea1e64f726aa51cb6c3b57 + +handshake=Noise_Npsk0_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cff66e55f9165514342e009262a3b2d4fb0efd940a5ae53f42f7 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7b2521d4d92735ed21e8ef9b635353c6cbbe6ba708e234d8d30c593af6091c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5a66f48e7581384a50a8a6197a76a21fe6e109f3b3c9c89cd335845970a875 + +handshake=Noise_Npsk1_25519_AESGCM_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542bf8c34c79ce1dd4da4984d89bde8e3c00ff7204e7e3e7845bf3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f2a1148bdbfaf3843292d3ad1d665cb11a83f1a412c3f9c04f6b876a91ff00 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=caa8b41e1b5d2289d4f8e91ee4587dbc6335873e1a9b1f9f4a220d3cbbdd2d + +handshake=Noise_K_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d181b2326033180d1efb21521b324a92 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=344e43356f1c93c5c345ff96d7671dc700a99d4c1a1e74a1fa6658219a7297 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=93a8163f0e969702549d39bae62a6f15eee1416ad8c1cbd5b545d77145cb16 + +handshake=Noise_Kpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543f880385cbbd4e4627713122b83ca89e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b60ace60531354a67160d9606e0db5d1a2a5949c7cd4bad2ab72bded373f09 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8de8b083b7c4450eadd4d2303cdff7325a8bd5fc54cb13054148818922c255 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bbd32e924225d5cd2f1e57426c23b774 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=13d2fe35d850dd95b05d9368e3cb118febf832bbc8d80810838747b10cbefc +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=970e52003f0ec0f427e4221354eb9ed099864d15a59ae15ed0b732843eb7c8 + +handshake=Noise_K_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c5672a9d770969769874994bbccf28d4db2f626566d3c3216351 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=344e43356f1c93c5c345ff96d7671dc700a99d4c1a1e74a1fa6658219a7297 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=93a8163f0e969702549d39bae62a6f15eee1416ad8c1cbd5b545d77145cb16 + +handshake=Noise_Kpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d8c11d84ff6ad4c09d4701841b7e57b976b0012be26f3a63234 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b60ace60531354a67160d9606e0db5d1a2a5949c7cd4bad2ab72bded373f09 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8de8b083b7c4450eadd4d2303cdff7325a8bd5fc54cb13054148818922c255 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6b065ba9cc0c626743f51ce46f94d811eb9452378e4517d832e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=13d2fe35d850dd95b05d9368e3cb118febf832bbc8d80810838747b10cbefc +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=970e52003f0ec0f427e4221354eb9ed099864d15a59ae15ed0b732843eb7c8 + +handshake=Noise_K_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254915e0cc0990344b65cbda0733b24186c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=344e43356f1c93c5c345ff96d7671dc700a99d4c1a1e74a1fa6658219a7297 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=93a8163f0e969702549d39bae62a6f15eee1416ad8c1cbd5b545d77145cb16 + +handshake=Noise_Kpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254beaf955b2e97b63a40e509e098e86d26 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b60ace60531354a67160d9606e0db5d1a2a5949c7cd4bad2ab72bded373f09 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8de8b083b7c4450eadd4d2303cdff7325a8bd5fc54cb13054148818922c255 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625406637d84bb2b8bacf583b157b5e2db6e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=13d2fe35d850dd95b05d9368e3cb118febf832bbc8d80810838747b10cbefc +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=970e52003f0ec0f427e4221354eb9ed099864d15a59ae15ed0b732843eb7c8 + +handshake=Noise_K_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c5672a9d7709697698742cd70ec0be61893c6605698abea0e701 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=344e43356f1c93c5c345ff96d7671dc700a99d4c1a1e74a1fa6658219a7297 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=93a8163f0e969702549d39bae62a6f15eee1416ad8c1cbd5b545d77145cb16 + +handshake=Noise_Kpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d8c11d84ff6ad4c09d4d1c82d14bc3fcc12126c67b2a0b7ed61 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b60ace60531354a67160d9606e0db5d1a2a5949c7cd4bad2ab72bded373f09 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8de8b083b7c4450eadd4d2303cdff7325a8bd5fc54cb13054148818922c255 + +handshake=Noise_Kpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6b065ba9cc0c626743f16dad8f22e8694edcec128ad0134b91f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=13d2fe35d850dd95b05d9368e3cb118febf832bbc8d80810838747b10cbefc +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=970e52003f0ec0f427e4221354eb9ed099864d15a59ae15ed0b732843eb7c8 + +handshake=Noise_X_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544bd123345f7c3f54a2b7c20f234b39aad2ea1bf7a9b83b82620158c18e0389f8faca2f68c69790e392e0e18c31f2b1e5db5eb720b8c88350be14c8c7f54b4e1c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1b4ae7e3fcfa6e15ab023def9162a31e3e34d0842a03269981ad4e7ec16542 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=51198ccfa5d72f8049fcfc80df71db7dcd5e35cda3f9f38684354627f9ee9d + +handshake=Noise_Xpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aea0c63d48d3b1d736b7c1aeae341160ba086d700161ae82ade3efff3235629ffd81d4a1b1e1fb50581c51d774c3293777a02a6bc95c753c273c08d942da964f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=36d0a83e220c3b0e9715e79ac127f50619a62397c7709f43121aa880b0242c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b132a81c4a9cbd2029363179f168112b8b245a15ac51be366f4cb2f09e8f60 + +handshake=Noise_Xpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625464d0a2b152420f100932269d5d383be29d5262c4287efbfc1a4689f88752b5e8e8564a7291e383dc088028b58775c5f40d61430c88439f36b3d04e1cfce91092 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5abf632a1e20300ec96b8849b1debe07702a0474191af8ec95d2120703ac0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0094ea104502c9337f6fdc742e949099f369f0f4c83a9327686b5fa3a39cb3 + +handshake=Noise_X_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544bd123345f7c3f54a2b7c20f234b39aad2ea1bf7a9b83b82620158c18e0389f8faca2f68c69790e392e0e18c31f2b1e5f22a97888834b9a0660e1fcdf45922e722d35e0d2441810979d3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1b4ae7e3fcfa6e15ab023def9162a31e3e34d0842a03269981ad4e7ec16542 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=51198ccfa5d72f8049fcfc80df71db7dcd5e35cda3f9f38684354627f9ee9d + +handshake=Noise_Xpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aea0c63d48d3b1d736b7c1aeae341160ba086d700161ae82ade3efff3235629ffd81d4a1b1e1fb50581c51d774c32937c1f988f1ae61819d1b63d42fa696048336ad771ced9bc5c747b1 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=36d0a83e220c3b0e9715e79ac127f50619a62397c7709f43121aa880b0242c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b132a81c4a9cbd2029363179f168112b8b245a15ac51be366f4cb2f09e8f60 + +handshake=Noise_Xpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625464d0a2b152420f100932269d5d383be29d5262c4287efbfc1a4689f88752b5e8e8564a7291e383dc088028b58775c5f4ef2c2f22b87d9c53accd687b92f198179e55ccc3ca701513b918 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5abf632a1e20300ec96b8849b1debe07702a0474191af8ec95d2120703ac0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0094ea104502c9337f6fdc742e949099f369f0f4c83a9327686b5fa3a39cb3 + +handshake=Noise_X_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544bd123345f7c3f54a2b7c20f234b39aad2ea1bf7a9b83b82620158c18e0389f897297750c1904bab4b5e0f28f2e027d71c9e88c0032221aa15011a8e4c78dffc +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1b4ae7e3fcfa6e15ab023def9162a31e3e34d0842a03269981ad4e7ec16542 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=51198ccfa5d72f8049fcfc80df71db7dcd5e35cda3f9f38684354627f9ee9d + +handshake=Noise_Xpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aea0c63d48d3b1d736b7c1aeae341160ba086d700161ae82ade3efff3235629f35e7632c0bd24a52daa0b948ba567229614147a2f9fec0650804c14558e7a4e3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=36d0a83e220c3b0e9715e79ac127f50619a62397c7709f43121aa880b0242c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b132a81c4a9cbd2029363179f168112b8b245a15ac51be366f4cb2f09e8f60 + +handshake=Noise_Xpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625464d0a2b152420f100932269d5d383be29d5262c4287efbfc1a4689f88752b5e86e5ef46c6d25996ebdb230b7431be817301ae3797b93cccfc4ecdf5ca4689916 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5abf632a1e20300ec96b8849b1debe07702a0474191af8ec95d2120703ac0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0094ea104502c9337f6fdc742e949099f369f0f4c83a9327686b5fa3a39cb3 + +handshake=Noise_X_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544bd123345f7c3f54a2b7c20f234b39aad2ea1bf7a9b83b82620158c18e0389f897297750c1904bab4b5e0f28f2e027d7f22a97888834b9a0660ee508b5c4c7f95b0d4d162d91e1123466 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1b4ae7e3fcfa6e15ab023def9162a31e3e34d0842a03269981ad4e7ec16542 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=51198ccfa5d72f8049fcfc80df71db7dcd5e35cda3f9f38684354627f9ee9d + +handshake=Noise_Xpsk0_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aea0c63d48d3b1d736b7c1aeae341160ba086d700161ae82ade3efff3235629f35e7632c0bd24a52daa0b948ba567229c1f988f1ae61819d1b637fb839283a338b00f93f9a7808911c16 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=36d0a83e220c3b0e9715e79ac127f50619a62397c7709f43121aa880b0242c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b132a81c4a9cbd2029363179f168112b8b245a15ac51be366f4cb2f09e8f60 + +handshake=Noise_Xpsk1_25519_AESGCM_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625464d0a2b152420f100932269d5d383be29d5262c4287efbfc1a4689f88752b5e86e5ef46c6d25996ebdb230b7431be817ef2c2f22b87d9c53accd25f4ff987e5fab341d7f7fb4079e5c4b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5abf632a1e20300ec96b8849b1debe07702a0474191af8ec95d2120703ac0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0094ea104502c9337f6fdc742e949099f369f0f4c83a9327686b5fa3a39cb3 + +handshake=Noise_NN_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846696b4bba7da775d1f343d26e248da47ba +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f2b3e233b31e5fb721769574df39f8da857cd538d2823ed04707c4f1efe2b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf606bbb94c9f27e8f8387140224a52189f3e5e131d5f9763f9ee83ffef688 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254317efadec3a319c5f4d92f4acde560c7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466755e7b455979bcf38ee9cf17a3b996b6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7fad8a5bf89774b591341ae6b5f9b53d55e70b6307fdb4fe2eee39c0e5bb79 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2da7ec97f80353b4fb9e44a0979a222e6cb7ec3d75b89ecca9a4d9aa7703b5 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ee343cd0b23aa39fd8cf07b1298ec783 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846651f5fc391bfbfd847e43586ac95db7e9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ad35e3ff791bbe3445b2bca0705f592f16908809ecc6d06940d6409849c628 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11feae6a0fb8493a4abbb530087f1d3835c4c62caecbe6f3f4dda89627825f + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625420a46675e8df604263bf11b7ac75590c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660bda10fa532c04667c79bda41d186c00 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bf2a56dc6366625ce68d4911f73aa10b2257c1b46ec516e590c5f94e10e9b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32d8849f8e77aaed40a8294d693acb51de2e22b290b24c779f5019595363f3 + +handshake=Noise_NN_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1385f964ae07e077013e92cfd34fa4d13aea47ab078af9d7bdc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f2b3e233b31e5fb721769574df39f8da857cd538d2823ed04707c4f1efe2b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf606bbb94c9f27e8f8387140224a52189f3e5e131d5f9763f9ee83ffef688 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254edb3ec0cb095fb513bfbb9898c1bdfb76968a05c706c7ccbbb3f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662f83f60a9da988d4cc0930126af5a85bcd6e46e1706d1e757c81 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7fad8a5bf89774b591341ae6b5f9b53d55e70b6307fdb4fe2eee39c0e5bb79 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2da7ec97f80353b4fb9e44a0979a222e6cb7ec3d75b89ecca9a4d9aa7703b5 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e18839475af8ae23cf85a15b391081786c60fb05ff38ff3a8166 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466493e02eaf3d3ce6c53105380003732a243a3a3519b790373372a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ad35e3ff791bbe3445b2bca0705f592f16908809ecc6d06940d6409849c628 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11feae6a0fb8493a4abbb530087f1d3835c4c62caecbe6f3f4dda89627825f + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e1ff8dc8fdbd3f5808a80493765e14512c58fa7091d993fbb79b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662ac11941a34258aed21d24c8ad4afccf638c0549785ab2b0dfa7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bf2a56dc6366625ce68d4911f73aa10b2257c1b46ec516e590c5f94e10e9b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32d8849f8e77aaed40a8294d693acb51de2e22b290b24c779f5019595363f3 + +handshake=Noise_NN_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664614a00ba4ea44ad9bf92954701ac9e1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f2b3e233b31e5fb721769574df39f8da857cd538d2823ed04707c4f1efe2b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf606bbb94c9f27e8f8387140224a52189f3e5e131d5f9763f9ee83ffef688 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625449313df1e7a1c4ae4b9f1e8920d00062 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466968db1bd797c81f1b67b2592fb59a167 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7fad8a5bf89774b591341ae6b5f9b53d55e70b6307fdb4fe2eee39c0e5bb79 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2da7ec97f80353b4fb9e44a0979a222e6cb7ec3d75b89ecca9a4d9aa7703b5 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f4d9e059d99a30cba39936c52fa6083 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667292e76b7244b2db0c173bab2da777a9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ad35e3ff791bbe3445b2bca0705f592f16908809ecc6d06940d6409849c628 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11feae6a0fb8493a4abbb530087f1d3835c4c62caecbe6f3f4dda89627825f + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540206ed2f7e2e7b5ad6db890bceeb2c33 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bbbf52db7d5d3002630dbe3b9e02cd98 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bf2a56dc6366625ce68d4911f73aa10b2257c1b46ec516e590c5f94e10e9b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32d8849f8e77aaed40a8294d693acb51de2e22b290b24c779f5019595363f3 + +handshake=Noise_NN_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1385f964ae07e0770131cf56bbcd8d5bd8379757412d0040b43 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f2b3e233b31e5fb721769574df39f8da857cd538d2823ed04707c4f1efe2b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf606bbb94c9f27e8f8387140224a52189f3e5e131d5f9763f9ee83ffef688 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254edb3ec0cb095fb513bfbbcecd94c12bd9847fd51060c21c2911b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662f83f60a9da988d4cc09b5792492a4e9b6409b7bc382d937669e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7fad8a5bf89774b591341ae6b5f9b53d55e70b6307fdb4fe2eee39c0e5bb79 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2da7ec97f80353b4fb9e44a0979a222e6cb7ec3d75b89ecca9a4d9aa7703b5 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e18839475af8ae23cf8593f99990833b96cecbed3efd278a3ccb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466493e02eaf3d3ce6c53103983ea03c55afa71148423e8f70f8361 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ad35e3ff791bbe3445b2bca0705f592f16908809ecc6d06940d6409849c628 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11feae6a0fb8493a4abbb530087f1d3835c4c62caecbe6f3f4dda89627825f + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e1ff8dc8fdbd3f5808a811debd72175c932bd7fa62ebdb9b2873 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662ac11941a34258aed21df1cd88b8c9f1a3c167e11a517c3e0152 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bf2a56dc6366625ce68d4911f73aa10b2257c1b46ec516e590c5f94e10e9b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32d8849f8e77aaed40a8294d693acb51de2e22b290b24c779f5019595363f3 + +handshake=Noise_KN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b231ab182aea5eb5058a6125ac8458a7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fa26e5cb486370ec737fd513a5cd5d0fe7d017427cab2b85eaf5047ace1c56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f7a9d96f5c7568769bdd7ce20df60b523b4b52280a088a5e2ab56711a80714 + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ec0b218b090f45287bb2306c93544b4c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0b9cffb44e4b2eeac1b962afcc87a27 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=52e8407c63693cd38f27a5315b73673dc02e994ef3f5c4713bf6638e95ce08 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f76678abb5d0cabbfa56bc6440c645fe8b1f05fc3e009b7414563e906ba769 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e8239d9793920e4c2d84ed8d8324b94b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666d84a1c9d27bc55b48b65cadb4a4d89c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d79d5ec5a8232269e46915e59d094941db2dcb0b171290dfed713b4446f6cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9c65816526946ffbdf3aac6904c4a12dcf5e447c7c30ecd25095493cea7790 + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254991b83d25a380fe7648c0dfcb9c155ab +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846652987ffb3b9f76e78d7121db589f4ac5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1a1745e5a72f77f23188f4ba70bf52e6129ad531108fdc545e5dee96bedbb4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05ced6b098b70097cf392ead659322b4f18485dc75bf8c6bf327debd0bf4cb + +handshake=Noise_KN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645fa9c2a20a197a1e0baa22bafe33ee7acaedae932270b7c48f2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fa26e5cb486370ec737fd513a5cd5d0fe7d017427cab2b85eaf5047ace1c56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f7a9d96f5c7568769bdd7ce20df60b523b4b52280a088a5e2ab56711a80714 + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625452c9fd84d58429beb1142b609a4863e7041b426ebeb347907ae7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f2455d2b3e74bed0cd965ad0906fdd426f1f658e2e90003dcf9e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=52e8407c63693cd38f27a5315b73673dc02e994ef3f5c4713bf6638e95ce08 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f76678abb5d0cabbfa56bc6440c645fe8b1f05fc3e009b7414563e906ba769 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce64f2a88f1e649de9503e6795ef215a1267bfc8c90aff062f8b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846623473963f18489e7c72234cee6d9a25976d89cb354d713db977b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d79d5ec5a8232269e46915e59d094941db2dcb0b171290dfed713b4446f6cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9c65816526946ffbdf3aac6904c4a12dcf5e447c7c30ecd25095493cea7790 + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548934c4e0268ed95c36d59d1129ecca39a1fb209dcbdf02a852d9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d4c687fac239e7d047928455aebf3d2b12e36ac54e367376775c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1a1745e5a72f77f23188f4ba70bf52e6129ad531108fdc545e5dee96bedbb4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05ced6b098b70097cf392ead659322b4f18485dc75bf8c6bf327debd0bf4cb + +handshake=Noise_KN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665d5971fcd8cf63d49da6f97e147f93f8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fa26e5cb486370ec737fd513a5cd5d0fe7d017427cab2b85eaf5047ace1c56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f7a9d96f5c7568769bdd7ce20df60b523b4b52280a088a5e2ab56711a80714 + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b86660a966446b42c03bed0de0739ce2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669f66fc60ac521937d189e4c5d6833ff6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=52e8407c63693cd38f27a5315b73673dc02e994ef3f5c4713bf6638e95ce08 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f76678abb5d0cabbfa56bc6440c645fe8b1f05fc3e009b7414563e906ba769 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254af63f6d98ab7abc10e584fbb1dadf03b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b8886f47e72b4d191b73e37aea007e84 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d79d5ec5a8232269e46915e59d094941db2dcb0b171290dfed713b4446f6cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9c65816526946ffbdf3aac6904c4a12dcf5e447c7c30ecd25095493cea7790 + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541e87f4eb6b35ffc2d7221c85e4fff91d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846607c20d3da79461e2b289a02a047412ce +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1a1745e5a72f77f23188f4ba70bf52e6129ad531108fdc545e5dee96bedbb4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05ced6b098b70097cf392ead659322b4f18485dc75bf8c6bf327debd0bf4cb + +handshake=Noise_KN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645fa9c2a20a197a1e0ba6bdff6753dbb6f06d4b3a58514071d26 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fa26e5cb486370ec737fd513a5cd5d0fe7d017427cab2b85eaf5047ace1c56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f7a9d96f5c7568769bdd7ce20df60b523b4b52280a088a5e2ab56711a80714 + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625452c9fd84d58429beb11458dae7d43d88d2bbf86bb4a4fea48851 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f2455d2b3e74bed0cd9697e5ae9b35f12f75d6837474b5847bcf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=52e8407c63693cd38f27a5315b73673dc02e994ef3f5c4713bf6638e95ce08 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f76678abb5d0cabbfa56bc6440c645fe8b1f05fc3e009b7414563e906ba769 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce64f2a88f1e649de9500f9bb110a1d4ab30625d3d655b0102e9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846623473963f18489e7c722561310a8b8d53b0cf6bd13b75020efd0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d79d5ec5a8232269e46915e59d094941db2dcb0b171290dfed713b4446f6cb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9c65816526946ffbdf3aac6904c4a12dcf5e447c7c30ecd25095493cea7790 + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548934c4e0268ed95c36d512d38ce5801c5f03b18df72af6fbc19c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d4c687fac239e7d04792a57bdb3a881474ad1192de0356b25394 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1a1745e5a72f77f23188f4ba70bf52e6129ad531108fdc545e5dee96bedbb4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05ced6b098b70097cf392ead659322b4f18485dc75bf8c6bf327debd0bf4cb + +handshake=Noise_NK_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625492cd9880ad23415b7d45ccc2b211e37a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665f57bb37f938df25d18d7f89288ae666 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4863a837542483bc5c39fe8dfcbae600696475bfdab8ae04beaa8e18cd1145 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ad73bc7f009fbd5df1bb517bfa9d9d5e262d056e50804f8bddb283d58befc2 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254242e465816d0858d06f47e335a09badb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846671f0a338acc3bde7238080dbb9973db1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e64f0f84675e48b7a0058285affc1fab6b836ac80b34e164082d18412d8a73 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2b2c8eab1a9fa483ab8b572c934cc44f2d41aa9dc4c536a1ddddea478da58 + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254620e726e3d7f18b8f25aede17cdfcfc8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846694d057301ab3e2f829e2432060dba030 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6df2429f1df587b56005e87298149cba35aa88ee298469397ea2f4b942dd63 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c7c8dbbad29b112d7602b04c8e22edb7eb74db82f6f776ea077a5f6690fbc + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541b074aab7776a1c52afe9b249fced5c0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846696313d3b21b1f68940958623dcca1294 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a3082562d366ded0f178cf1d204e4e53db5736e66ec10eb0c866a37e654d15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60a2f051f6f113e03215df5a29be54632358fd03a7d3dc49e0771fe6c0d2b0 + +handshake=Noise_NK_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f0908050e933b7b9347e67893173878d10adab8cf0a44ce2a3f1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846618559bbbc6d87c6cb0347e9b2bbbf21fe5d8af2c7ce5ee0d82e0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4863a837542483bc5c39fe8dfcbae600696475bfdab8ae04beaa8e18cd1145 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ad73bc7f009fbd5df1bb517bfa9d9d5e262d056e50804f8bddb283d58befc2 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e51a799a96f84a256118fdc303fec0ed8998042d5dd9556ae77c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846687204b49e4a67b7b4ca7cd645ff191190a3ca23e92be635c8585 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e64f0f84675e48b7a0058285affc1fab6b836ac80b34e164082d18412d8a73 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2b2c8eab1a9fa483ab8b572c934cc44f2d41aa9dc4c536a1ddddea478da58 + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254de5deba8d0093296a30ef145e306b54d8bc4a3969c7afb2b0677 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d26056f711dacca0102501cb818f217ca8fb2563e79ad50daa19 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6df2429f1df587b56005e87298149cba35aa88ee298469397ea2f4b942dd63 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c7c8dbbad29b112d7602b04c8e22edb7eb74db82f6f776ea077a5f6690fbc + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254976601e4078212f0b67b7352b3d82247b7412614ac64b5b73e33 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661d05dac14245dacbe1ce8860abf4e4e9c39a079a99de750d3cc0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a3082562d366ded0f178cf1d204e4e53db5736e66ec10eb0c866a37e654d15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60a2f051f6f113e03215df5a29be54632358fd03a7d3dc49e0771fe6c0d2b0 + +handshake=Noise_NK_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3a1fd96effa4a96c2d4d2ea49fa51b4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe5aaf6d285a1b2eb29a83b4041f8a9f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4863a837542483bc5c39fe8dfcbae600696475bfdab8ae04beaa8e18cd1145 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ad73bc7f009fbd5df1bb517bfa9d9d5e262d056e50804f8bddb283d58befc2 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f8d95af05ef4f548190140e105fcdd2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe1e5b2875f805c4c7afe1276551ac33 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e64f0f84675e48b7a0058285affc1fab6b836ac80b34e164082d18412d8a73 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2b2c8eab1a9fa483ab8b572c934cc44f2d41aa9dc4c536a1ddddea478da58 + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541cf92667ae758693dd2b7399cd15c401 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d345d580e11e4c26c7ebfbee575455e9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6df2429f1df587b56005e87298149cba35aa88ee298469397ea2f4b942dd63 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c7c8dbbad29b112d7602b04c8e22edb7eb74db82f6f776ea077a5f6690fbc + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254879ef3d63c164584553d294c6d91d571 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6f430402252f77e17be906eaf0b20eb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a3082562d366ded0f178cf1d204e4e53db5736e66ec10eb0c866a37e654d15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60a2f051f6f113e03215df5a29be54632358fd03a7d3dc49e0771fe6c0d2b0 + +handshake=Noise_NK_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f0908050e933b7b9347e44301dc6d6ca7d4b0ce776f3a5d90c38 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846618559bbbc6d87c6cb03495d7531bcb04bb2c87bb444037256131 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4863a837542483bc5c39fe8dfcbae600696475bfdab8ae04beaa8e18cd1145 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ad73bc7f009fbd5df1bb517bfa9d9d5e262d056e50804f8bddb283d58befc2 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e51a799a96f84a25611826e1b4d3a08e33859de2e2edaa19276c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846687204b49e4a67b7b4ca7e048fc2bd060f346d69f4fa196666869 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e64f0f84675e48b7a0058285affc1fab6b836ac80b34e164082d18412d8a73 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f2b2c8eab1a9fa483ab8b572c934cc44f2d41aa9dc4c536a1ddddea478da58 + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254de5deba8d0093296a30e16abbe1699580f3543369780626f053b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d26056f711dacca01025391e489dd6b23eb6f17f68551e051e17 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6df2429f1df587b56005e87298149cba35aa88ee298469397ea2f4b942dd63 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c7c8dbbad29b112d7602b04c8e22edb7eb74db82f6f776ea077a5f6690fbc + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254976601e4078212f0b67b3067d831eba76e2c57e6e4f5d0e5e2bb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661d05dac14245dacbe1ceb5b28b786b8224cdf48be55fc33b7f9e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a3082562d366ded0f178cf1d204e4e53db5736e66ec10eb0c866a37e654d15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60a2f051f6f113e03215df5a29be54632358fd03a7d3dc49e0771fe6c0d2b0 + +handshake=Noise_KK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254559236449548b149c86010ab38a7f593 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cb6a3f46c1a9e3740e073e00c1278116 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=12833dc9ced7ce2bd117611fb110e611bc98f046edd326de308589b085aec1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fc60d948d36347b0907c4ab7f180becf7427ef90bb45e71eb35503a2a77271 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b2feab58971b2b7754c4ce9c28c926e8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466570f0cf3fa53a65d939d10b1642c2b53 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bf212c1518bfc1bcb836c5fe6f669aff33ac43ef009c4a8ec7276ccd7fd1e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ff7971613fb38b2ceff9e02ab8bbef225ec3cf67b862f6edd347d64868d589 + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b254229e7b1620584147ca90cb8b10f5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663967c7ece58722039816225411448d25 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f0c4ac1a0669c88f81275a19747e2947aafe72519b9f9acf69a1853369b81 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cb84c8fb19d854105cdccfcf0d69f4b2022e872c1a8825fa459a8da32c574 + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471902189942423b5e706181d24bd3da6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466670e12b11fa0a2fc1efa881c5b3c5d60 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6a1cea393611538d818a6e0ad35dba2df91c82dc22142061d38de575a1be8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=850511dc2048fec84f31a5ddbbacc370f515c762a439bc4064953b3a60d1c3 + +handshake=Noise_KK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254142884550c3a5bbba542498fe2a2e3a42ae03427648d643f2ffa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf84137217e17d4ad6644f9f0c5a674e3acd0fa5cd6b82cf17a5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=12833dc9ced7ce2bd117611fb110e611bc98f046edd326de308589b085aec1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fc60d948d36347b0907c4ab7f180becf7427ef90bb45e71eb35503a2a77271 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625424595376448ec2517751f60303af508d12946b045ec39c9f603d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b72308d275634efa109e4144199e333ac5c65da8025b13ba4993 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bf212c1518bfc1bcb836c5fe6f669aff33ac43ef009c4a8ec7276ccd7fd1e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ff7971613fb38b2ceff9e02ab8bbef225ec3cf67b862f6edd347d64868d589 + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546ce1b92921238f610b81af38c19ef2fa4eb392fae936496df41d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d2b19549f76d4caa90b4e495ba5af97e098cadfdd780d76d76f0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f0c4ac1a0669c88f81275a19747e2947aafe72519b9f9acf69a1853369b81 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cb84c8fb19d854105cdccfcf0d69f4b2022e872c1a8825fa459a8da32c574 + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543127c95b934bb1414f3123125be999be4d09da6b81e0cc56ae20 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846662111f0c62246c844c4f7d015feb0c15934e2b3b4a838f789485 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6a1cea393611538d818a6e0ad35dba2df91c82dc22142061d38de575a1be8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=850511dc2048fec84f31a5ddbbacc370f515c762a439bc4064953b3a60d1c3 + +handshake=Noise_KK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548cafd0193d81be006185db284ec2d871 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0afb2bac37e2e2d9c68db47d4036c22 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=12833dc9ced7ce2bd117611fb110e611bc98f046edd326de308589b085aec1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fc60d948d36347b0907c4ab7f180becf7427ef90bb45e71eb35503a2a77271 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549235d028fae66b4f1e4dccfb170d03f8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0928131e420581b197828694275da40 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bf212c1518bfc1bcb836c5fe6f669aff33ac43ef009c4a8ec7276ccd7fd1e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ff7971613fb38b2ceff9e02ab8bbef225ec3cf67b862f6edd347d64868d589 + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542f62675567432d076a0e477c3cf14615 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662095be79364e992976531966ba961c94 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f0c4ac1a0669c88f81275a19747e2947aafe72519b9f9acf69a1853369b81 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cb84c8fb19d854105cdccfcf0d69f4b2022e872c1a8825fa459a8da32c574 + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540dc6b77672c010e87e1636b5d1da2360 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c86fc32118e4ace4d027a4522d94d9d0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6a1cea393611538d818a6e0ad35dba2df91c82dc22142061d38de575a1be8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=850511dc2048fec84f31a5ddbbacc370f515c762a439bc4064953b3a60d1c3 + +handshake=Noise_KK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254142884550c3a5bbba542d6529e3c81cc3f6ce831243b3346b035 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf84137217e17d4ad6640ddd193fa49edc3b9fb577a2c7a8296c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=12833dc9ced7ce2bd117611fb110e611bc98f046edd326de308589b085aec1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fc60d948d36347b0907c4ab7f180becf7427ef90bb45e71eb35503a2a77271 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625424595376448ec2517751fb29003363a17cb6d53130cc3125c606 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b72308d275634efa109eaf94f98070fefad6378fa12be3916c5d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bf212c1518bfc1bcb836c5fe6f669aff33ac43ef009c4a8ec7276ccd7fd1e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ff7971613fb38b2ceff9e02ab8bbef225ec3cf67b862f6edd347d64868d589 + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546ce1b92921238f610b819d25ee0e9a4161cfae2e38cb26b28809 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d2b19549f76d4caa90b4f153ed8bf441a8a8ee9d18587bb6f6d0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0f0c4ac1a0669c88f81275a19747e2947aafe72519b9f9acf69a1853369b81 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cb84c8fb19d854105cdccfcf0d69f4b2022e872c1a8825fa459a8da32c574 + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543127c95b934bb1414f31387bd610396d2cc4f94ea7aa7135f8dc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846662111f0c62246c844c4f136c97d8afb760c73f285dcb7f366545 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6a1cea393611538d818a6e0ad35dba2df91c82dc22142061d38de575a1be8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=850511dc2048fec84f31a5ddbbacc370f515c762a439bc4064953b3a60d1c3 + +handshake=Noise_NX_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664c97f89674eace3b56f9d5fb417a8ff75418944771131814c57a29365b15b48bca3f3ce4a7f4e53112bf6ef3bdf7f964a0cfd9784f9efcd4c52a446c50c555a7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2ea99baffa3692333bc13d7af3e454bf9acae4d796013d1ff35c0678ee84e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=789c1800de969242141310282d5b91629248bdf66631e3b45e7b8c2207ff89 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ab929c145cf0c1c676452b550524b5e8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846637d8b8996a822fcfe7e5b0d643443ffdc9ede527b1163f4b0dc6daf2322831ceefd299f1510d6504b291d8bcd98ff5cd96ce4ce180517d440d58c057749bee68 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=38a8c7da03d0c27bfe3051c07c463722d336ebac343c864773be3b5b559f72 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6e6cb9df11c3f09dd93c34bf894ab97f1a0375ffe48719f83e201d35a9ecfd + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625482eadd90b062837066000cd5e2896e72 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663f756d65f4f5ee577e6b0d67d96f7aa2ff3ceb944f3abaf9587b4fa8511edd9ec6cf250413b660aa38b93a65f8e4acaf51406c51b75d4b6622e81c30e4bf5f7e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccfd7afc1ab48b43dc8768ee6912d7e72799002904654b41f797d7c3f88e09 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=743635953fe8aef503710cdc126dbe837a53d24ab0413f469f720689f7cbfe + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254407912b4ed86d5812b6b2d9d6c0c9e33 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846628135288ad23fb032bc1ee5c922fbfe7fbb69668b9480571f36552e43984d6c7fbb160a0867a8e086fb093630e10460ccdf5e0b7f7135bb5871b31518976d993 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92eb54dd636d5ca48c96325fecb8b92b31a40cad65edca5c6602fbf71f4397 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d13070af6c2bac6cc30637e54b8fe2ed1a5030c624e4b691c9fdd2e4c42ae2 + +handshake=Noise_NX_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664c97f89674eace3b56f9d5fb417a8ff75418944771131814c57a29365b15b48b2a593850eb6e640bdf72e859d3e6d378a72eb960dcbbb05601c67d08ca00bcf0d473e958a30b311e179a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2ea99baffa3692333bc13d7af3e454bf9acae4d796013d1ff35c0678ee84e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=789c1800de969242141310282d5b91629248bdf66631e3b45e7b8c2207ff89 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bc226ac1952daf37daccafd280d738f198a8829e1fcbd4be1c95 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846637d8b8996a822fcfe7e5b0d643443ffdc9ede527b1163f4b0dc6daf2322831ce525bf68b693695fba0cc6e523a646896093271a3cb9c1ed45414b7cf0f501cc694dd21e19994b7181d27 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=38a8c7da03d0c27bfe3051c07c463722d336ebac343c864773be3b5b559f72 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6e6cb9df11c3f09dd93c34bf894ab97f1a0375ffe48719f83e201d35a9ecfd + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254561fea27227285c680b595365022f8742ce5869972e379fa1b8a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663f756d65f4f5ee577e6b0d67d96f7aa2ff3ceb944f3abaf9587b4fa8511edd9e1a721a420612fbd0c23865f4bfbca2ec8930db64dacc0b33e0b529391699f00e32e8524ab9ac3e59e4f9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccfd7afc1ab48b43dc8768ee6912d7e72799002904654b41f797d7c3f88e09 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=743635953fe8aef503710cdc126dbe837a53d24ab0413f469f720689f7cbfe + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625406509ecaf4beb0e75208c257af685179db7a99e146ed89d8e60a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846628135288ad23fb032bc1ee5c922fbfe7fbb69668b9480571f36552e43984d6c7fd154ee04b21546f594953ca8d7753ace88e3c6d9dc176114056980d5c6ffe52778163ff1e4fe114605c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92eb54dd636d5ca48c96325fecb8b92b31a40cad65edca5c6602fbf71f4397 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d13070af6c2bac6cc30637e54b8fe2ed1a5030c624e4b691c9fdd2e4c42ae2 + +handshake=Noise_NX_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664c97f89674eace3b56f9d5fb417a8ff75418944771131814c57a29365b15b48b79b4c07534af976280cbab579afc3f9cd0526a61d1adc06ef7359cf6e64ede9d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2ea99baffa3692333bc13d7af3e454bf9acae4d796013d1ff35c0678ee84e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=789c1800de969242141310282d5b91629248bdf66631e3b45e7b8c2207ff89 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e2cead811ebab45234d6015348300217 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846637d8b8996a822fcfe7e5b0d643443ffdc9ede527b1163f4b0dc6daf2322831ceb8bdffc1fb9e2f056f5924ddb7a079c5d7a0dd8ba258a660986cda0b0fb82865 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=38a8c7da03d0c27bfe3051c07c463722d336ebac343c864773be3b5b559f72 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6e6cb9df11c3f09dd93c34bf894ab97f1a0375ffe48719f83e201d35a9ecfd + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f39bc63b0a4dd6191e4289f80a68c16f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663f756d65f4f5ee577e6b0d67d96f7aa2ff3ceb944f3abaf9587b4fa8511edd9e719735f519b112f0f590ca884ba289f8b8977d3a36530e5d79baf821cace360a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccfd7afc1ab48b43dc8768ee6912d7e72799002904654b41f797d7c3f88e09 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=743635953fe8aef503710cdc126dbe837a53d24ab0413f469f720689f7cbfe + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c3f341235ad4e85cdfff4007e328673 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846628135288ad23fb032bc1ee5c922fbfe7fbb69668b9480571f36552e43984d6c72b962f3774ebc05cb6d6810641c40c14ac72883a7bf88a59f7f771d54e9f978e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92eb54dd636d5ca48c96325fecb8b92b31a40cad65edca5c6602fbf71f4397 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d13070af6c2bac6cc30637e54b8fe2ed1a5030c624e4b691c9fdd2e4c42ae2 + +handshake=Noise_NX_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664c97f89674eace3b56f9d5fb417a8ff75418944771131814c57a29365b15b48befea2db797f55a7ad5a71d072c64f323a72eb960dcbbb05601c6ca9847c52cb0cd36528e3c656343f4b6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2ea99baffa3692333bc13d7af3e454bf9acae4d796013d1ff35c0678ee84e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=789c1800de969242141310282d5b91629248bdf66631e3b45e7b8c2207ff89 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bc226ac1952daf37dacce78ea0cfd6b5afe05702919e81f51f7a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846637d8b8996a822fcfe7e5b0d643443ffdc9ede527b1163f4b0dc6daf2322831cecb38d9a801b214d126a66f637984d09c093271a3cb9c1ed4541471b1923c474467a450d3dc13d7be7bb4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=38a8c7da03d0c27bfe3051c07c463722d336ebac343c864773be3b5b559f72 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6e6cb9df11c3f09dd93c34bf894ab97f1a0375ffe48719f83e201d35a9ecfd + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254561fea27227285c680b5754de721d3c3568396f3d10ccc48ea7f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663f756d65f4f5ee577e6b0d67d96f7aa2ff3ceb944f3abaf9587b4fa8511edd9eb6b62b52923328c4a7cf9daf752282f58930db64dacc0b33e0b5eed6945d0bb7b4809f6caaeb6e5d03d4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccfd7afc1ab48b43dc8768ee6912d7e72799002904654b41f797d7c3f88e09 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=743635953fe8aef503710cdc126dbe837a53d24ab0413f469f720689f7cbfe + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625406509ecaf4beb0e752085be87b067f55e9c0d7500f9b4e626a18 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846628135288ad23fb032bc1ee5c922fbfe7fbb69668b9480571f36552e43984d6c749a43f9525b52730c1483dc2d4f707c9e88e3c6d9dc176114056694fa32638eda14593e6fefc5c276cda +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92eb54dd636d5ca48c96325fecb8b92b31a40cad65edca5c6602fbf71f4397 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d13070af6c2bac6cc30637e54b8fe2ed1a5030c624e4b691c9fdd2e4c42ae2 + +handshake=Noise_KX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645f7f537bba7b00980084360bc2a659d49462e51c7aac16f5974c5fcc3abd6f05f7ed6592d8f264aa7f21684cad38af385cfe03524ba2327236490bf28542d7f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42b90acd27dcf671c7d1f62b4ecceb4825c5ce3bd8c44f5957ef56822bf50f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=45ddb566084ceec6fc0adc2e814ff0c6d07ae69e7248f0551c198b71a0d783 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548544e4275a97c99ec7854f30013ee77f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a61295b2a49e6bd40fc40e1a1f28ac34130cac3377f7343efb28e1b707a2299659cb923f1f226e2978fd4733e78a8223a7a694eaeac15deff1b257a8ffd29d2c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=422e6f132671f31c057aa12609a08e6b971f81cd27be000592cd40301af11e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=55484c7bd5558711b44c2a32e603b34964dc0e927db52282255636934440f0 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e9b221e00cdcbb650b72e970ff83babb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0f71c06a5716d87cbb5d97a45053222a6d60e07a582ce9dce1155d4fcaa192fb519550ab9024a779c2636ab49bf3ba56dab990ce321a23b1280c59bce5ce4dd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a2c799c936e5eba4d7d21ac769ae2a887414f8f9b3d2220952f64ca948411d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4947d1bc4ccf44d845765ed79859094e2bf493b78c605ae3be52e5c4a03173 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b7d1ddd1aca55c78b5120a7f4cf4d092 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e441b3d7203d59162fdf03aecb1e9abc3fc65c102f49d381190d2ce7d9396fb02c53f0a687a80ff806d2c1953981b2023b75750f4a37944f1938b03cdf278b9b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd13dbc237f374adb0ecb695c24ad344784f57393b09efafe0aef543a510ff +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=76e66c4f498fccd441d67019c0e9274449c9c2711054daa2dc1ad1b2e302c9 + +handshake=Noise_KX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645f7f537bba7b00980084360bc2a659d49462e51c7aac16f5974c5fcc3abd6f0d0784ff6a1efe6404d97729b19faf7bf96e2147355ad9eae84ed96d9b0276e18f4c96d3a563f50dd6bc6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42b90acd27dcf671c7d1f62b4ecceb4825c5ce3bd8c44f5957ef56822bf50f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=45ddb566084ceec6fc0adc2e814ff0c6d07ae69e7248f0551c198b71a0d783 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b006bf285e1cc8449eefb4803696a072f96625e392032412ac7b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a61295b2a49e6bd40fc40e1a1f28ac34130cac3377f7343efb28e1b707a22996043e592d42da12d8eecdd160890c22ca8ee70aa30463a615c058d6e9c5a3740a312c13c8ee955dcdf6cc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=422e6f132671f31c057aa12609a08e6b971f81cd27be000592cd40301af11e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=55484c7bd5558711b44c2a32e603b34964dc0e927db52282255636934440f0 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540fe2a78085f7d670d1705b765c61bda640f638b04934aff5d2df +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0f71c06a5716d87cbb5d97a45053222a6d60e07a582ce9dce1155d4fcaa192ffd8284d74683b696a160b63590b75addda2fa2fffc3c20e6b1b1a6239f770840ffc3245f7e0bac0b134b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a2c799c936e5eba4d7d21ac769ae2a887414f8f9b3d2220952f64ca948411d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4947d1bc4ccf44d845765ed79859094e2bf493b78c605ae3be52e5c4a03173 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548908a58a36d8dc3bee25fb17d21656ca9d006c84e231e9391a54 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e441b3d7203d59162fdf03aecb1e9abc3fc65c102f49d381190d2ce7d9396fb09b82de351bf3309dcc311af9eaf338c126bfd57f36960aa25616ae53b38a2081e943aeed082c3d3a00a4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd13dbc237f374adb0ecb695c24ad344784f57393b09efafe0aef543a510ff +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=76e66c4f498fccd441d67019c0e9274449c9c2711054daa2dc1ad1b2e302c9 + +handshake=Noise_KX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645f7f537bba7b00980084360bc2a659d49462e51c7aac16f5974c5fcc3abd6f008d091837372254d9904e61d91b53baa4e6613a4a57cf930b2e4fc137a1f8a0f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42b90acd27dcf671c7d1f62b4ecceb4825c5ce3bd8c44f5957ef56822bf50f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=45ddb566084ceec6fc0adc2e814ff0c6d07ae69e7248f0551c198b71a0d783 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541e114d4616248178fa6a52bebfa79fb8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a61295b2a49e6bd40fc40e1a1f28ac34130cac3377f7343efb28e1b707a22996e0565a8630f96f31796cd72f87e78d69075097a2f17b4f37a7945a2bdea2ceef +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=422e6f132671f31c057aa12609a08e6b971f81cd27be000592cd40301af11e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=55484c7bd5558711b44c2a32e603b34964dc0e927db52282255636934440f0 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d57e59a6963d53021f5bfcd757ae8b39 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0f71c06a5716d87cbb5d97a45053222a6d60e07a582ce9dce1155d4fcaa192fa0d104f5bc8e28c5f959f1a55333a948ba80cbdebd704e58e1f6b05d8eff2ba1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a2c799c936e5eba4d7d21ac769ae2a887414f8f9b3d2220952f64ca948411d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4947d1bc4ccf44d845765ed79859094e2bf493b78c605ae3be52e5c4a03173 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541326b4b1cbb8a627c7e589b8c8fdcc16 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e441b3d7203d59162fdf03aecb1e9abc3fc65c102f49d381190d2ce7d9396fb05b27cd488484ecb9437e1737a38fc727b7010d60deda8b391d9d0f72d20d5c75 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd13dbc237f374adb0ecb695c24ad344784f57393b09efafe0aef543a510ff +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=76e66c4f498fccd441d67019c0e9274449c9c2711054daa2dc1ad1b2e302c9 + +handshake=Noise_KX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645f7f537bba7b00980084360bc2a659d49462e51c7aac16f5974c5fcc3abd6f09af46abfbaeb6c9a0231e7469a859de896e2147355ad9eae84ed9a52883bed02d1ec49e1ae5ca88674a2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42b90acd27dcf671c7d1f62b4ecceb4825c5ce3bd8c44f5957ef56822bf50f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=45ddb566084ceec6fc0adc2e814ff0c6d07ae69e7248f0551c198b71a0d783 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b006bf285e1cc8449eef9d8fc5d2f9c711e1987b7781167bbce8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a61295b2a49e6bd40fc40e1a1f28ac34130cac3377f7343efb28e1b707a22996c8d1923fde7f66216702d15a384adb718ee70aa30463a615c058779d93896d68e450351480fe181da78d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=422e6f132671f31c057aa12609a08e6b971f81cd27be000592cd40301af11e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=55484c7bd5558711b44c2a32e603b34964dc0e927db52282255636934440f0 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540fe2a78085f7d670d1700d3c687f29c6956ddd271352b018d110 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0f71c06a5716d87cbb5d97a45053222a6d60e07a582ce9dce1155d4fcaa192fb691b582e5aad280c365586d54fb8d21da2fa2fffc3c20e6b1b1e333d00ab6b0bdd0ce17e547e8763bbc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a2c799c936e5eba4d7d21ac769ae2a887414f8f9b3d2220952f64ca948411d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4947d1bc4ccf44d845765ed79859094e2bf493b78c605ae3be52e5c4a03173 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548908a58a36d8dc3bee258dc3cc2bff1ebac4572450a310136fee +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e441b3d7203d59162fdf03aecb1e9abc3fc65c102f49d381190d2ce7d9396fb0e670c75a1572c5ed4b7c4e18d7163a1226bfd57f36960aa25616a6fb8b27806eb6782f97b72d49760bed +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd13dbc237f374adb0ecb695c24ad344784f57393b09efafe0aef543a510ff +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=76e66c4f498fccd441d67019c0e9274449c9c2711054daa2dc1ad1b2e302c9 + +handshake=Noise_XN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b7d8187d170dc771df11b75334183868 +msg_2_payload= +msg_2_ciphertext=486ffb188e214980067c5ce19591b4f1b1497b971e30ec91d31bd5c18b2373eac8edba0652ee3830483af64f81eacbe644efedbbd6c6734d1aa3f9c1461a8576 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=226c1a7a3eb2ff97ae113d905d56489f5e91b56ad36d333552fdac29ff293b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5569f84032223b1fcb28d9def11fc807b8225089859bc49d3a44662b5bc6c5 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540b4e435539b8778fc984a53142ed1d34 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b4d4b525b6a1fe1a4464adbff47ccec3 +msg_2_payload= +msg_2_ciphertext=deb852db81c970c53f0a9a457e8b31cb53509a146199636fcd465c9eebac538ef5ec27d761da511083aae47bc8ec9960bf67814876f646456759f6eec5d88c6c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0b8b61050fed8c393461e28e7173106096d992680a0a8fca2c5bec37cf37cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9ad22402add33878374568727e1dba89ed39b3a7f35cd144b7caa45785aee7 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540e408809b80401244941dccac4134cce +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660b85c6e758641aea77c2ad7f6144cad0 +msg_2_payload= +msg_2_ciphertext=332d57a13424aceba27618d8fe8b6de96775b8398e39238994a737fe68fa680962032e627ce9923882a92f67c0200ea13206085252dcc1647aefb4ecbdedda58 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e7251e6b6625a32bf85fac6b5e34f833254989fc5aa63cf11fa032af49245 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f05530f84856a293384329c4ce0f0798bc4410a52046d7edfdd4d2ec05948f + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545477d3a3ba67a624953cebab6b281d08 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e071471a5398a3bd50445adca4df941e +msg_2_payload= +msg_2_ciphertext=027fe3c8ca06bd4f6e10c6388005c09ce6c0f4b298ab7f3a15c158c15337d93773846a9cd490ea54b678e1ffd60fe5012ddb586af2f165ae0cb7170dc06346c6 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e9acbdf9ffd865c840598217601d320c40073cc16cd7ab5e106c4d37d26987 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3f7a01de8c7b17dc99849ff8fa6aa8c6b8c43f6ce86203d745ef09c6c010b2 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543f6a7217dc75ca41c3911066ee0c5906 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846681afbb042c41e679d53667fd78ea7e5d +msg_2_payload= +msg_2_ciphertext=e506abe8229dce20fb1e15484b101bff86d8d5431f6c63f434ee31d67021a62a943306cd45edf878bc45efc723919fa751dfae61f5b3180d8202fe6efaaddd63 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ce3255a6c24fb66e413c8543cb8f09d97f1750639337c5c322fbf37a2cd501 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d96d7282e64170d7fc4074bca3d778f7f165116cf28fe5e74fa7b330e7e400 + +handshake=Noise_XN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f377bb64185a9cf7ce1e379602e74ba38c07c1c2a026e64c5c0 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=486ffb188e214980067c5ce19591b4f1b1497b971e30ec91d31bd5c18b2373ea0643c46b29a4dde3164a69a808d90fc150d900caad0def5ed10015cb05452802c0bcfc5bfba885906427 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=226c1a7a3eb2ff97ae113d905d56489f5e91b56ad36d333552fdac29ff293b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5569f84032223b1fcb28d9def11fc807b8225089859bc49d3a44662b5bc6c5 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f57ad03ee30a67ff8595ba7dfaec76aff61a89df1685273c8f9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466335cb281f418f7ba439a5c4908155e68796ecca86a44354e6302 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=deb852db81c970c53f0a9a457e8b31cb53509a146199636fcd465c9eebac538ee70af9fc35a0bd839e0fbbceb2ceb941e19257a7b6f06c69994a69538ef20315caef2035d664312e94a8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0b8b61050fed8c393461e28e7173106096d992680a0a8fca2c5bec37cf37cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9ad22402add33878374568727e1dba89ed39b3a7f35cd144b7caa45785aee7 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542c69b0ed12a80ca70a0fe657a10cb63cd99468f1acbd8224dd3a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466305a1f920e8c82b47fa496c53a37ca8b20b660ee4b0773293763 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=332d57a13424aceba27618d8fe8b6de96775b8398e39238994a737fe68fa6809a3f1b6876708addc7a53f4ebef97a9c3b6452c76d8dfe69b69b7e66522dbabb18e487eef49646e903148 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e7251e6b6625a32bf85fac6b5e34f833254989fc5aa63cf11fa032af49245 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f05530f84856a293384329c4ce0f0798bc4410a52046d7edfdd4d2ec05948f + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543247f4ea8236ed9947cc1415f9206c59465f532b848a94591cc9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c40676ef641ec2b2b6fa7e9334283fdd4229bed03af0d6e991ca +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=027fe3c8ca06bd4f6e10c6388005c09ce6c0f4b298ab7f3a15c158c15337d937872b1ede7375d1ad8ea688f5c5b9beadd1213591f5456e0c3dc7f839a6dade8a748b51a74090cb670467 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e9acbdf9ffd865c840598217601d320c40073cc16cd7ab5e106c4d37d26987 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3f7a01de8c7b17dc99849ff8fa6aa8c6b8c43f6ce86203d745ef09c6c010b2 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544892c27a1b4e4768d4e362aac34f05fdad78747fc1cce5c6e338 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466612e19645b49e373cff7e818c5721ae3c024a618d2d66b2e5d18 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e506abe8229dce20fb1e15484b101bff86d8d5431f6c63f434ee31d67021a62aeb922a2abac14eecd904de08848e215259172644930ac13ed24d67d1916560d540a7b1ca02a6b926819d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ce3255a6c24fb66e413c8543cb8f09d97f1750639337c5c322fbf37a2cd501 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d96d7282e64170d7fc4074bca3d778f7f165116cf28fe5e74fa7b330e7e400 + +handshake=Noise_XN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669d3c26f842cdf05230729fc44c7a617c +msg_2_payload= +msg_2_ciphertext=486ffb188e214980067c5ce19591b4f1b1497b971e30ec91d31bd5c18b2373eac5b11685a2f87b7ac31c1a4b49778680d8620b814c325c89cf286565822004aa +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=226c1a7a3eb2ff97ae113d905d56489f5e91b56ad36d333552fdac29ff293b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5569f84032223b1fcb28d9def11fc807b8225089859bc49d3a44662b5bc6c5 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c44b17b7d0bf45d77e5f96b055ab6fe9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eadbd5bfbb94389829adc583de19d424 +msg_2_payload= +msg_2_ciphertext=deb852db81c970c53f0a9a457e8b31cb53509a146199636fcd465c9eebac538ee6bff14bc3846ad6f76e5e0a90bbc6dd7960a92ae9c64e42a2eb40900a6f4cd5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0b8b61050fed8c393461e28e7173106096d992680a0a8fca2c5bec37cf37cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9ad22402add33878374568727e1dba89ed39b3a7f35cd144b7caa45785aee7 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b2097565e2f0b03f343ad91768d3314e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669fc5e675e71a75698278b4300d53e87b +msg_2_payload= +msg_2_ciphertext=332d57a13424aceba27618d8fe8b6de96775b8398e39238994a737fe68fa6809311fb0f9264244e60cb48b4b6058629f30afa9f509bbd838d24ef120770e1cc8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e7251e6b6625a32bf85fac6b5e34f833254989fc5aa63cf11fa032af49245 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f05530f84856a293384329c4ce0f0798bc4410a52046d7edfdd4d2ec05948f + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547ffc3fa91240b5932693ed3b9db99d7c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660acd02cb99ac2db8313b5182b3179b3b +msg_2_payload= +msg_2_ciphertext=027fe3c8ca06bd4f6e10c6388005c09ce6c0f4b298ab7f3a15c158c15337d93738742ee35f8cfbd59e125a8035b560c9f20867cc11dd0b27e4df6fa43326c234 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e9acbdf9ffd865c840598217601d320c40073cc16cd7ab5e106c4d37d26987 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3f7a01de8c7b17dc99849ff8fa6aa8c6b8c43f6ce86203d745ef09c6c010b2 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6146b34b323c78f9818412261244901 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f451ca4aecda85a294a53bce469d770d +msg_2_payload= +msg_2_ciphertext=e506abe8229dce20fb1e15484b101bff86d8d5431f6c63f434ee31d67021a62ac5c7fef3e518ee12feee90444548094aa9b60bfbc5d1e32de454077812a6e3c9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ce3255a6c24fb66e413c8543cb8f09d97f1750639337c5c322fbf37a2cd501 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d96d7282e64170d7fc4074bca3d778f7f165116cf28fe5e74fa7b330e7e400 + +handshake=Noise_XN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f377bb64185a9cf7ce16283bd3daf6d9c0ba6c497733575cc6c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=486ffb188e214980067c5ce19591b4f1b1497b971e30ec91d31bd5c18b2373ea663e0df03962627965e5fcaa901f5dff50d900caad0def5ed1006938800ab47acddce47a5db586f73fc5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=226c1a7a3eb2ff97ae113d905d56489f5e91b56ad36d333552fdac29ff293b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5569f84032223b1fcb28d9def11fc807b8225089859bc49d3a44662b5bc6c5 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f57ad03ee30a67ff85978adde877f716279533e0a2229a4aab7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466335cb281f418f7ba439abe510d34d9184008ae80207850403aa6 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=deb852db81c970c53f0a9a457e8b31cb53509a146199636fcd465c9eebac538ec7e4e29b1af4f63c31a16d9f340a38b8e19257a7b6f06c69994a70c8c156b8ebcaab740791146667087c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0b8b61050fed8c393461e28e7173106096d992680a0a8fca2c5bec37cf37cf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9ad22402add33878374568727e1dba89ed39b3a7f35cd144b7caa45785aee7 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542c69b0ed12a80ca70a0f8816914cd7fb3040fd3220ca32168832 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466305a1f920e8c82b47fa444a556e2e6905911b42f7d3f12eef8d1 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=332d57a13424aceba27618d8fe8b6de96775b8398e39238994a737fe68fa6809906b387fbc92454cb8e3ce80aa3ce2d1b6452c76d8dfe69b69b752a7b14c6e906bb630d10bfb0708286e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e7251e6b6625a32bf85fac6b5e34f833254989fc5aa63cf11fa032af49245 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f05530f84856a293384329c4ce0f0798bc4410a52046d7edfdd4d2ec05948f + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543247f4ea8236ed9947cc4a8d0fece6a150beb0461a04c507ad2f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c40676ef641ec2b2b6faec1bf71f0b73312bd4d55c65fb531c84 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=027fe3c8ca06bd4f6e10c6388005c09ce6c0f4b298ab7f3a15c158c15337d93775dc62f002272f6904411b71bd08dbc6d1213591f5456e0c3dc79ac833bef0e945cd83a245502521d272 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e9acbdf9ffd865c840598217601d320c40073cc16cd7ab5e106c4d37d26987 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3f7a01de8c7b17dc99849ff8fa6aa8c6b8c43f6ce86203d745ef09c6c010b2 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544892c27a1b4e4768d4e3f54bce40707a191b272b69140d3400f9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466612e19645b49e373cff732ad5876325b056b774da6e2856fcc76 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e506abe8229dce20fb1e15484b101bff86d8d5431f6c63f434ee31d67021a62a5274f6f82b572bcc2ccc52af86d6615c59172644930ac13ed24d153f267d66d2b3dcb2236a3719f343bf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ce3255a6c24fb66e413c8543cb8f09d97f1750639337c5c322fbf37a2cd501 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d96d7282e64170d7fc4074bca3d778f7f165116cf28fe5e74fa7b330e7e400 + +handshake=Noise_IN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466659213d4ce7051561fa9c93bb500a945 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19a1c0a20452d8a44b7254cab212c1ff1098a0651a73ab58812290a0d9baee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01c7222fc0c22585ce1032e012d225e0fc53213dabde8f5dfc15ea2f5173ea + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625426df4f9c2999bafe403964ea11975f86af2d3f459ca54211b55e0b49a37beb70989b57c41d71288d7a645427e31f0cb2dcbb4db539c677da4af178d31053d13a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fc20123316e7891f44ad163404fe4a4c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84725e6c75c8c0b1b97c0e28ee7b19b576c6a60866bd79dd3131d5ee51c24b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8590802179dc26ea74bfc6a974cf1ff0e3b2873d1d35056fd1ff7864f9a644 + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625481808305f9d7b92b5ea8b8862b86f62c20567a3bd4dc220e0ccf2fc62558f235f4678aaae2b806b4a90aae519295ec01a41b4407fe9d17f084c2ddda16124140 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846663791a12da21572632f46c02df0a7406 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84f2db9466d00f52a3fc9f0ee6c04d3424921a32d74e43ab7b257e2df0dcbe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7770c9796a35e3e0d64d35adc860ce54d86eebe105e3755636ae56b0e5fa08 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625441fcbd1030f49b2f467e42d08b039c8155bf36a93cf9933e2a8e39f0f0b5c49eaef35880826277e28a79b5eef2b86e0128f1343d8389fca6107a00d2091138bb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b53337b2ea8b7ee8ddf33c94e6759ac2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce2558df09ff72b190aeae3894c7a7c1151a9b52117ee855995f2695ce43ec +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8eb7770ec52590ee4f3803a3872fc02a6587d149f84deef14fb72ebd4d5316 + +handshake=Noise_IN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466711652c1b7ae42adf79af77d71534b43a53dcf922ba05ae2ac7b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19a1c0a20452d8a44b7254cab212c1ff1098a0651a73ab58812290a0d9baee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01c7222fc0c22585ce1032e012d225e0fc53213dabde8f5dfc15ea2f5173ea + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625426df4f9c2999bafe403964ea11975f86af2d3f459ca54211b55e0b49a37beb70989b57c41d71288d7a645427e31f0cb232047a7659ec1068a88fe5cb7ea21be467b78d47b7baaa05dd34 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667981f9efb8ad730403563a2f5370ba187c5246e8c27ada9bf8cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84725e6c75c8c0b1b97c0e28ee7b19b576c6a60866bd79dd3131d5ee51c24b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8590802179dc26ea74bfc6a974cf1ff0e3b2873d1d35056fd1ff7864f9a644 + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625481808305f9d7b92b5ea8b8862b86f62c20567a3bd4dc220e0ccf2fc62558f235f4678aaae2b806b4a90aae519295ec01ba8237f6d9105d8c7474d97f153c5ecfabcef174ccba4e2a9bb3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a4757a7db35fc286d20a61dd38f374ceecfa44f66620f277856c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84f2db9466d00f52a3fc9f0ee6c04d3424921a32d74e43ab7b257e2df0dcbe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7770c9796a35e3e0d64d35adc860ce54d86eebe105e3755636ae56b0e5fa08 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625441fcbd1030f49b2f467e42d08b039c8155bf36a93cf9933e2a8e39f0f0b5c49eaef35880826277e28a79b5eef2b86e01c6a207bd5e919c675a0d17f7e14db1a8f0e8579e6b1d2e095981 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668a013bee4be51ef49d047f6d038c5a2b395957690fabaaf40d07 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce2558df09ff72b190aeae3894c7a7c1151a9b52117ee855995f2695ce43ec +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8eb7770ec52590ee4f3803a3872fc02a6587d149f84deef14fb72ebd4d5316 + +handshake=Noise_IN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e7150a9dca189b7510ad6a70e6729e8a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19a1c0a20452d8a44b7254cab212c1ff1098a0651a73ab58812290a0d9baee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01c7222fc0c22585ce1032e012d225e0fc53213dabde8f5dfc15ea2f5173ea + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625426df4f9c2999bafe403964ea11975f86af2d3f459ca54211b55e0b49a37beb70342f60d7e017a9e508697e93d78355b626535fa190a36dfeb02ac6a7fdbd31d4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466caf39580058278ca5b56e3e092908720 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84725e6c75c8c0b1b97c0e28ee7b19b576c6a60866bd79dd3131d5ee51c24b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8590802179dc26ea74bfc6a974cf1ff0e3b2873d1d35056fd1ff7864f9a644 + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625481808305f9d7b92b5ea8b8862b86f62c20567a3bd4dc220e0ccf2fc62558f235ecc21fa53263c3bb8c5ea661ed2cf0737c66bc33295664c78a4aa3223be0f3fa +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666a306aae194994874c7879ee8810f5a1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84f2db9466d00f52a3fc9f0ee6c04d3424921a32d74e43ab7b257e2df0dcbe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7770c9796a35e3e0d64d35adc860ce54d86eebe105e3755636ae56b0e5fa08 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625441fcbd1030f49b2f467e42d08b039c8155bf36a93cf9933e2a8e39f0f0b5c49e63b930768aafd11bace041ce31e6a2ec456951153dbc13db98f6e98ddeb32dbd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846646c106fc6f2c865265abbb262b1bdbf6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce2558df09ff72b190aeae3894c7a7c1151a9b52117ee855995f2695ce43ec +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8eb7770ec52590ee4f3803a3872fc02a6587d149f84deef14fb72ebd4d5316 + +handshake=Noise_IN_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466711652c1b7ae42adf79ab3dc343dc9ace7a3bfccac12de3d193e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19a1c0a20452d8a44b7254cab212c1ff1098a0651a73ab58812290a0d9baee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01c7222fc0c22585ce1032e012d225e0fc53213dabde8f5dfc15ea2f5173ea + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625426df4f9c2999bafe403964ea11975f86af2d3f459ca54211b55e0b49a37beb70342f60d7e017a9e508697e93d78355b632047a7659ec1068a88ff75c4bc0591d93395bd4e06b6e8754e6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667981f9efb8ad730403567813ca21163470293e3c6fc41b4ff0b4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84725e6c75c8c0b1b97c0e28ee7b19b576c6a60866bd79dd3131d5ee51c24b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8590802179dc26ea74bfc6a974cf1ff0e3b2873d1d35056fd1ff7864f9a644 + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625481808305f9d7b92b5ea8b8862b86f62c20567a3bd4dc220e0ccf2fc62558f235ecc21fa53263c3bb8c5ea661ed2cf073ba8237f6d9105d8c74744d93349fc84b57b4fc980737d4759e01 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a4757a7db35fc286d20a1fcad775e56c67beb054c7f519c576d3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84f2db9466d00f52a3fc9f0ee6c04d3424921a32d74e43ab7b257e2df0dcbe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7770c9796a35e3e0d64d35adc860ce54d86eebe105e3755636ae56b0e5fa08 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625441fcbd1030f49b2f467e42d08b039c8155bf36a93cf9933e2a8e39f0f0b5c49e63b930768aafd11bace041ce31e6a2ecc6a207bd5e919c675a0d4c6555c46b7ad60a6449338078640754 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668a013bee4be51ef49d04e4373184dee4d8c2281669b66728d233 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce2558df09ff72b190aeae3894c7a7c1151a9b52117ee855995f2695ce43ec +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8eb7770ec52590ee4f3803a3872fc02a6587d149f84deef14fb72ebd4d5316 + +handshake=Noise_XK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d7fcb95d9da87e0af29cde0d6a5f287b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466800ac1687176d90bc6dbdf12863c0537 +msg_2_payload= +msg_2_ciphertext=92d38f089b41f951d834dddd45dbe5578c4021370d7e1a9478a94746309363a29763127dc08fe1cb8dc065082573ee096c7dc4e1c36837953f4916fc7b19dd03 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2415b54e0f4f9843d8ef7a77448791fbb4c3c1335e88c0fc9f0ca1a48996b4 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3653f1a64137245561ea386294c3c0954715d3e1f4b85effccbe2d1c43475f + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625445c2cc340ab6003689ddce8eada9ceae +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466214e4e1d6596bc62ea7cd6275cddfc39 +msg_2_payload= +msg_2_ciphertext=969813a2bee54c8d740a7f931ccff98baa6416e7cb8508e45e71e9e3932508ace41c99953f1325ad580dcf7a989586edfa0b6ee8ef46e5463098f735198874ff +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=839b155ed75c4053ce6a815306226060349a013205fc9418aa2e5a05e37fa7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=40dba082e6da9293e21b496c9e74c7978542ba104874a6331fe12168b67099 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543421b40e4c4da5824f33d5ed970d4c72 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466878d6a9f1192586ed358e91ee5cc1649 +msg_2_payload= +msg_2_ciphertext=8c1add204692080de004b0a79d901205d9ffbdbf7c23f1514c5ef9b3df2d4f71a9c91cc9c8ed052dbe6b8094ea588ec5cc703fc8be9632d41756df774ff82907 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5700577bd6d3c9d2d1c0a2a5fed1c4de71869859a03099dfeb03bd981ace7d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2ec9ab876956dd0f236c33bca7c4b91ca0e3108a7c03f666bb04ef89e17d02 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b396f9a7b3a726986fab49e66bb7c0f4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d2ee8fa782dfe01926052719a57dbdfa +msg_2_payload= +msg_2_ciphertext=7c6c099d0438335855eeaa6c87ab89415079528c4d87469b62959bc66189837a43b24f63b056b84462dabb2d4be549a20f11a5bd4bcce092df24f07d4d69e22a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3fd3d739b18b4fc970e126c41893b2739f3d30b49d67035184b72dd87a838f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=562d5785a73f04b43264dc1e800df65988cc7aeec98090a77f256c0dea1305 + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d4aa8d15cf148942f35d8bdf1c9f2c05 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc0625a4f8b32dc5a768fd83880c493e +msg_2_payload= +msg_2_ciphertext=3f8f3799dfea7cd0b81bb96415f330d3e3f48ad1fc352c0b153cbbb230e97ab018a17ec22c9f3c5545f201227668b6536d82c4e45e3adfa8d4161327b89ca439 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86042248607aea3d2a79be1388836b47969b9142baea780518c4c44e525d0a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7916c1051c9968838d6217df3ece55302168b2c76d4e69c7460e24535a50d9 + +handshake=Noise_XK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254776fe5c02a96e95f6fc556ee66374ae786b903528d1b295d7522 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846676130dd92e35bd3dfea9939c3c01914d86fca24d8f05612dd2d7 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=92d38f089b41f951d834dddd45dbe5578c4021370d7e1a9478a94746309363a2485c5233cd0a9b22da8a2729920c6b3a9c61297320c75dc288dc9270fd8679c519e87538ecc20b18e9aa +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2415b54e0f4f9843d8ef7a77448791fbb4c3c1335e88c0fc9f0ca1a48996b4 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3653f1a64137245561ea386294c3c0954715d3e1f4b85effccbe2d1c43475f + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254098b5c955eb34a1b4c11491a1f25da104f9c12a6560e4a3a0200 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b3fa1fabeefa5b4f170db9a8eaa1888997cd3da3b60c71ba397c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=969813a2bee54c8d740a7f931ccff98baa6416e7cb8508e45e71e9e3932508acd7b63294dde8d5c5bbea7739f023f46211824e8ba66e2079622d5865f7db5720f0291f54435b44d00169 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=839b155ed75c4053ce6a815306226060349a013205fc9418aa2e5a05e37fa7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=40dba082e6da9293e21b496c9e74c7978542ba104874a6331fe12168b67099 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b5ab168f947be648453704b3b95edcfd75bec637735a93a2fb2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661aa93bf01cd6e3e7f949ca31898cfa6d2556c8377ac6193d5cfd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8c1add204692080de004b0a79d901205d9ffbdbf7c23f1514c5ef9b3df2d4f711dcebb94fb27d3f54b01284f85fd7ef6037e46e0de1b083d799cca20dd026b4bd3773a7a117e4f9c5692 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5700577bd6d3c9d2d1c0a2a5fed1c4de71869859a03099dfeb03bd981ace7d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2ec9ab876956dd0f236c33bca7c4b91ca0e3108a7c03f666bb04ef89e17d02 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545720b91a9dcab61c37b8814561cda01c19a5f7bfea89802537d1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c8a84bf5a002e9e393ff048a9a6b9cf1f09d44b4aaa089d2640e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7c6c099d0438335855eeaa6c87ab89415079528c4d87469b62959bc66189837a0ead89bdd77510a4f3e8fd591d591345386ce238a665fe32d93ed7c485fab009e51b239ebcacf940abbe +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3fd3d739b18b4fc970e126c41893b2739f3d30b49d67035184b72dd87a838f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=562d5785a73f04b43264dc1e800df65988cc7aeec98090a77f256c0dea1305 + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bf7b785a3e9cc3a60cfa3d1704700697f33e32e082282b754d78 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a867c4b84b57de8e777468abbf7194d6daedca28b6a2122b1249 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3f8f3799dfea7cd0b81bb96415f330d3e3f48ad1fc352c0b153cbbb230e97ab02b4a3292e06f079eeb610e5d7ac8438a1c93d192615dfb4da0b725cd90e7976e2f26faad75511b079923 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86042248607aea3d2a79be1388836b47969b9142baea780518c4c44e525d0a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7916c1051c9968838d6217df3ece55302168b2c76d4e69c7460e24535a50d9 + +handshake=Noise_XK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dc4410806334bcafc02c5f0288cba55f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ae416864308a4715413b37adefce89bb +msg_2_payload= +msg_2_ciphertext=92d38f089b41f951d834dddd45dbe5578c4021370d7e1a9478a94746309363a227f611ff53b50b0d3218258cf499c7fd9e8957ea5c45de361b798573cedf448c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2415b54e0f4f9843d8ef7a77448791fbb4c3c1335e88c0fc9f0ca1a48996b4 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3653f1a64137245561ea386294c3c0954715d3e1f4b85effccbe2d1c43475f + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f48adffda573b586253f36b35ae765f6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846609630930c7e2c7cde8bd1c87e650eba8 +msg_2_payload= +msg_2_ciphertext=969813a2bee54c8d740a7f931ccff98baa6416e7cb8508e45e71e9e3932508ac1fbd3cbb304e67b87c76c4e11c571046ba79b4fd1fc6b3d4ba4a5fc9b2077171 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=839b155ed75c4053ce6a815306226060349a013205fc9418aa2e5a05e37fa7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=40dba082e6da9293e21b496c9e74c7978542ba104874a6331fe12168b67099 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ad3cb547b0f1ba018228d6d48b1302d6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466363e99dcad427a100c62c4fca6743d44 +msg_2_payload= +msg_2_ciphertext=8c1add204692080de004b0a79d901205d9ffbdbf7c23f1514c5ef9b3df2d4f712c00e0a7262263bc0fa2f498110f3023d6d614065bd937c3dcc68aa42afb9f53 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5700577bd6d3c9d2d1c0a2a5fed1c4de71869859a03099dfeb03bd981ace7d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2ec9ab876956dd0f236c33bca7c4b91ca0e3108a7c03f666bb04ef89e17d02 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d1b0d8db64424f07a17edfe37cd6ecbb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662600630bebba156d21b4352295cf1587 +msg_2_payload= +msg_2_ciphertext=7c6c099d0438335855eeaa6c87ab89415079528c4d87469b62959bc66189837a5300ba1f27066ab0f8ac8ff29be25d7e9e38b5a86438cc7efc8a58302284255a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3fd3d739b18b4fc970e126c41893b2739f3d30b49d67035184b72dd87a838f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=562d5785a73f04b43264dc1e800df65988cc7aeec98090a77f256c0dea1305 + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c6abbd65f6352017e41b0526f935d4fa +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f7e5ebfdda054bed9fe6a6234d6a7c2a +msg_2_payload= +msg_2_ciphertext=3f8f3799dfea7cd0b81bb96415f330d3e3f48ad1fc352c0b153cbbb230e97ab0d6f8f274d7ee267767e3e543ad1fbc4ec3ce0f6dd3939eb8a98e87dabbf62d75 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86042248607aea3d2a79be1388836b47969b9142baea780518c4c44e525d0a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7916c1051c9968838d6217df3ece55302168b2c76d4e69c7460e24535a50d9 + +handshake=Noise_XK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254776fe5c02a96e95f6fc57a9232ae7515f60452f85bcbe3e6f292 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846676130dd92e35bd3dfea9dcd8a750ba80f0fd88e6996bcee6f1c1 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=92d38f089b41f951d834dddd45dbe5578c4021370d7e1a9478a94746309363a278d070e8c58bf3524d8f197ab037fdcb9c61297320c75dc288dc39f19360875d6111c307664b3a0bf0ac +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2415b54e0f4f9843d8ef7a77448791fbb4c3c1335e88c0fc9f0ca1a48996b4 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3653f1a64137245561ea386294c3c0954715d3e1f4b85effccbe2d1c43475f + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254098b5c955eb34a1b4c110d747d4a36bf21cb8bc8c804f71c68f0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b3fa1fabeefa5b4f170d48ee6e86ab0f45624d5a3a909b3a9b11 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=969813a2bee54c8d740a7f931ccff98baa6416e7cb8508e45e71e9e3932508acc694f7a253f0ce275ea72ee17d008b7f11824e8ba66e2079622d9ef5fb46dc9543ea8892f8f24d34aaba +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=839b155ed75c4053ce6a815306226060349a013205fc9418aa2e5a05e37fa7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=40dba082e6da9293e21b496c9e74c7978542ba104874a6331fe12168b67099 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b5ab168f947be648453c179b7a5f141728783b58a14c7856fbe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661aa93bf01cd6e3e7f949145e514380905712cb7cb7c81fdcc1b4 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8c1add204692080de004b0a79d901205d9ffbdbf7c23f1514c5ef9b3df2d4f71a2ed70c8feada07998dbcdd38ca4a29a037e46e0de1b083d799cf6ab0c35ba161be8e6beb6a93c5e4dbc +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5700577bd6d3c9d2d1c0a2a5fed1c4de71869859a03099dfeb03bd981ace7d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2ec9ab876956dd0f236c33bca7c4b91ca0e3108a7c03f666bb04ef89e17d02 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545720b91a9dcab61c37b8fdab24849c2062acdd29252d4b53b370 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c8a84bf5a002e9e393ffda17842e6b4e3cb0f50b0225f5fc489f +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7c6c099d0438335855eeaa6c87ab89415079528c4d87469b62959bc66189837ae6e466d4af2f9686cb8df36fc22fd85f386ce238a665fe32d93e355fda6cff6b81c94b84931e25c047a9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3fd3d739b18b4fc970e126c41893b2739f3d30b49d67035184b72dd87a838f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=562d5785a73f04b43264dc1e800df65988cc7aeec98090a77f256c0dea1305 + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bf7b785a3e9cc3a60cfa1fae5337fa8886d55a06d82e213d5459 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a867c4b84b57de8e7774f3198fd17a166131b3ecfd7ae59d1406 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3f8f3799dfea7cd0b81bb96415f330d3e3f48ad1fc352c0b153cbbb230e97ab0608a59baf1cd8cbf237675a276c86abc1c93d192615dfb4da0b736a363083920a7853b3732d4aa37de18 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86042248607aea3d2a79be1388836b47969b9142baea780518c4c44e525d0a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=7916c1051c9968838d6217df3ece55302168b2c76d4e69c7460e24535a50d9 + +handshake=Noise_IK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a38fd17d3ecfc034b8662c49ba22d8558729800e0313b725febfb2ec77bd84a2bf740c07e5cfd9d0a2d377198bb3e525fa18b100686908255ea1150d9a8001ca +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669f9a4611a8a2078190bdb54616a8918f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c69889e3504ff2c2199e28029aea578cd758b4214a3c8b83f92b5ee66670ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36198b611040f132bd465de67099a9ddf9dfe3f23bd1f2d30c943b26c3fb5a + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9d7e098f29f8d60de3d6535f46b2d89cb9366382ef8243cbf9c650eab2dc27f01d46a576445054a4d2e2df4b1f220cce5e9325db888b8d29e5d8f4fd9a77fe0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ebddc558f82c368423bc3e5e00700f2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=116b1de8e063d67a8d8c5be83a7f444168b60447df326749434d22cf39ffb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=035f0315fdae44c8c718fa8509fc00c55ea3f4e322a500888874b90593f113 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540b5b9c6666fe0610f8de010548ef7b2c1ff9cfdcd2a35d7257c0f14cf6b65792b0e9536d43e2b8d36cf8ac0d1e756d4757cb9f9f3bdd55b5cfdb5954d3063844 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660da82bcd895d1b8199ddcb12ab5ddfca +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cce3a32168d9494773586dbc7599e2c94e401f0936e3696e91b8a00209601 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2f113c945e331cd45962508eee9d01907800a7b4f611d2d5264fdeb96a81ff + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540193347cd7c4197ad710ce0f36a4c24fc4da2c0b271e51f178b900abb6361298e62d4d75c6fe9a49584fe9ca40f5cd5e60c071e7738477042185ec854f83b76e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466af3fef0028d1964b618ae069d56fb155 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1f941586981ee8e35546c4c825ae5b59f085ec1ac261c913667246bc609496 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c7df30218d05a737fb405b7067cfd591d593d111fe1847d086ae37e806dda8 + +handshake=Noise_IK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a38fd17d3ecfc034b8662c49ba22d8558729800e0313b725febfb2ec77bd84a2bf740c07e5cfd9d0a2d377198bb3e525e9cee2fc198c757f297517fc5be735549e54d9d557fc96f7c5ff +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb139fe5e49c4d60a6ecd193505e01bdb218399d78150c11ce8d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c69889e3504ff2c2199e28029aea578cd758b4214a3c8b83f92b5ee66670ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36198b611040f132bd465de67099a9ddf9dfe3f23bd1f2d30c943b26c3fb5a + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9d7e098f29f8d60de3d6535f46b2d89cb9366382ef8243cbf9c650eab2dc27f01d46a576445054a4d2e2df4b1f220ccbcbfc9a0cec566f4a3969cbd5264c8e59adf9c11031617ce7d24 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f0e11f5f201496d65ded674476b0378052ce43ff98321c35654d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=116b1de8e063d67a8d8c5be83a7f444168b60447df326749434d22cf39ffb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=035f0315fdae44c8c718fa8509fc00c55ea3f4e322a500888874b90593f113 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540b5b9c6666fe0610f8de010548ef7b2c1ff9cfdcd2a35d7257c0f14cf6b65792b0e9536d43e2b8d36cf8ac0d1e756d47c6cf8ace27084be59885bf4844fadfd9dfc1592f3179058ea7bc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660e207c946b72c6e772588dbd81244e6e87253cf9703c4156ed65 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cce3a32168d9494773586dbc7599e2c94e401f0936e3696e91b8a00209601 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2f113c945e331cd45962508eee9d01907800a7b4f611d2d5264fdeb96a81ff + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540193347cd7c4197ad710ce0f36a4c24fc4da2c0b271e51f178b900abb6361298e62d4d75c6fe9a49584fe9ca40f5cd5ea873d705aef61f8a6af29492c9e58fa7bc5094ff240e4edb4aa4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ee3ad6bce0a3efbf171d998ea2f0255498e25d9bce8287eb8da8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1f941586981ee8e35546c4c825ae5b59f085ec1ac261c913667246bc609496 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c7df30218d05a737fb405b7067cfd591d593d111fe1847d086ae37e806dda8 + +handshake=Noise_IK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a38fd17d3ecfc034b8662c49ba22d8558729800e0313b725febfb2ec77bd84a2108f69d924cca3b15ef92569d7ec2cdd6548391e29b99f96e7b5a5091b8a9f93 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846657c9117c74762c3957ec726fa608e616 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c69889e3504ff2c2199e28029aea578cd758b4214a3c8b83f92b5ee66670ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36198b611040f132bd465de67099a9ddf9dfe3f23bd1f2d30c943b26c3fb5a + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9d7e098f29f8d60de3d6535f46b2d89cb9366382ef8243cbf9c650eab2dc27fbad3ba213848dbb944b7105fdd6ab12b7fe76265452d31ddd7f0f01fe0eec744 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f44a254be52605ed2a0053cc0650c99 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=116b1de8e063d67a8d8c5be83a7f444168b60447df326749434d22cf39ffb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=035f0315fdae44c8c718fa8509fc00c55ea3f4e322a500888874b90593f113 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540b5b9c6666fe0610f8de010548ef7b2c1ff9cfdcd2a35d7257c0f14cf6b6579241f7b7d690f1bded3fca5448cc406d3e1005ef58c3ccd169ec72b2f7c4caa8b6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846605b9566b5b0f3deb72a002560de9d6bc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cce3a32168d9494773586dbc7599e2c94e401f0936e3696e91b8a00209601 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2f113c945e331cd45962508eee9d01907800a7b4f611d2d5264fdeb96a81ff + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540193347cd7c4197ad710ce0f36a4c24fc4da2c0b271e51f178b900abb636129853d2066d323ef55180074e4e958c318e1bd8c9457e081991c320902e9eca0b16 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466934c3609b2ea20856de72db441812028 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1f941586981ee8e35546c4c825ae5b59f085ec1ac261c913667246bc609496 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c7df30218d05a737fb405b7067cfd591d593d111fe1847d086ae37e806dda8 + +handshake=Noise_IK_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a38fd17d3ecfc034b8662c49ba22d8558729800e0313b725febfb2ec77bd84a2108f69d924cca3b15ef92569d7ec2cdde9cee2fc198c757f2975da3efa4e0d0fe13a9991b9411ba4c0e2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb139fe5e49c4d60a6ec8c83fb024bc79e49670113142aa6c652 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c69889e3504ff2c2199e28029aea578cd758b4214a3c8b83f92b5ee66670ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=36198b611040f132bd465de67099a9ddf9dfe3f23bd1f2d30c943b26c3fb5a + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9d7e098f29f8d60de3d6535f46b2d89cb9366382ef8243cbf9c650eab2dc27fbad3ba213848dbb944b7105fdd6ab12bbcbfc9a0cec566f4a39606ee8a4f74c5bab0347ec3820d2283e5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f0e11f5f201496d65ded4b10d20841f311688cda5dc987c59676 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=116b1de8e063d67a8d8c5be83a7f444168b60447df326749434d22cf39ffb1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=035f0315fdae44c8c718fa8509fc00c55ea3f4e322a500888874b90593f113 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540b5b9c6666fe0610f8de010548ef7b2c1ff9cfdcd2a35d7257c0f14cf6b6579241f7b7d690f1bded3fca5448cc406d3ec6cf8ace27084be59885e4091c5bc209109dda7507f4d707739b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660e207c946b72c6e77258c2aadc838c8dc6ef181eec060394556c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cce3a32168d9494773586dbc7599e2c94e401f0936e3696e91b8a00209601 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2f113c945e331cd45962508eee9d01907800a7b4f611d2d5264fdeb96a81ff + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540193347cd7c4197ad710ce0f36a4c24fc4da2c0b271e51f178b900abb636129853d2066d323ef55180074e4e958c318ea873d705aef61f8a6af212d4915462886947dcbffa4ffeb7444d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ee3ad6bce0a3efbf171dc4555c0b4c715a52ac5e3c7f2e249d3e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1f941586981ee8e35546c4c825ae5b59f085ec1ac261c913667246bc609496 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c7df30218d05a737fb405b7067cfd591d593d111fe1847d086ae37e806dda8 + +handshake=Noise_XX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aaf8bd6d4f4015e5465aea27ce9bfe2f9cfeb1b38ee28d45032fe0b31e0ed19185e606afae8d39560d71c245a09c231c58f90ea85bc24bfda03e505c65b792c3 +msg_2_payload= +msg_2_ciphertext=d91be69fde3995104e4827d77d5162d8757250d035b74525efccce98e892ed62d34f840a4785fe4cc548a096f803652e4fbe69376911d114fd5e11c994720434 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55ac89364861faed9538fe931a2bf90878fa10072b3c5e520b733728948e1c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4a9308221816fe917b617d45c8a1f8bdb8adafec2bb9ab2f8bd6b1627bf9e1 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625402675bce88ab5a820c99ea9fddb39f02 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466581a3db6c8617d78b487458dfc00147b77d9a8f9d55d33fa54e9a099348118f922577a9a42ebe899869e0a3c8c9311d4232fd9b2bb0fdc2c004994d87467c928 +msg_2_payload= +msg_2_ciphertext=4f14513ce6f321d3e3cb4585286a18c666e6b3777ae346a7480f09dca7af5575e88a84a7d6f8a2e72183e95e71bc8d3f22b1d51f739ea46e9429f03e4491eb26 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=53f77a183580b9f1fbcef4857976951cff9f90e21cca7a4fe7cddd5303b23f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25166ac4cc0f48a5e9a1af15f86c0a4b065a0c587aaadbcfb76ca98540431 + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625485c5ada7d6d53105c13610ffcf41d7a4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c5c243ed69e6c32a5c5016b1b66676d6076aede0fd2df3c89b58f2df5a3ed2cf603ab6a12b364a8b0f64fec5081f97aeaeb9a99414e7b0eb091667e33c7d8f6c +msg_2_payload= +msg_2_ciphertext=77f77a124d513addd8faed07d38add6dc885d466a1f3f259847430780d121ac5272da5fda9f0a5f69039d94ebe69d0b526e42143bd74f784fc79fd2210c0d5a3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd96a733132ce4bf0bb7f1fbffffd0e2cc805e2b2bc5b4c14684d1370e93fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73803758314e6aa57533c404442d54e9f3c6f94157c41d2d82cf608158473e + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625479170a96b76ee24ab783821e5383da8a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665239caf37bac645326193f36abf47c49b4568ab9ea3933a8dab0a835393c23e3a4a9a936fef8c1d46b9a591a9684ffec5b876aecad0fcdeaa22a6d7b6bc8bbdf +msg_2_payload= +msg_2_ciphertext=561aa523426011b76cd099db2c038f6405739eee844f4f59da33c6c315bebf276d70e2ea113233792b32d752c6d4a256fad013cfee5f910ee4922b5a7720b2e0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c188211012160a32e31359391f5d3bd9ebe2af466c2c3759d36d7f1b723a53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=330f1b1616e11def88c53fefeede6e62e5c89414516dc4f3eb55cc0a6dd244 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b448543164c221df43ad2e76d7dce619 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eb1b0ba3208b9285c46d88de673268c0a9c11d1372df5c12348027d7b20d33e3678bcacb6dc7ecffae94384891ee38abeccb20a835ddbf929d0a313fb26d4ee4 +msg_2_payload= +msg_2_ciphertext=6008678f2ef024bf48e09a421bfa274e0e134657e952b07b9628b88938f8489ae1bd41cf9f2af850d9e4186aef156e71671537a7673853392bddc33c073f660d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f0fdc970b0edc1b34eff18de0753b76a4c407c63c75dfa31b7718a25bd9852 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=058345e46ccb2548fdff3835a49a67f7470b5e1d7c58b338e64ca4350b3bca + +handshake=Noise_XX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aaf8bd6d4f4015e5465aea27ce9bfe2f9cfeb1b38ee28d45032fe0b31e0ed191f5384372c5963ff9a47437d7781bbfa1ede85376a07ee6cffe47f4274e311338859dfb4dd4f0d9c1e87e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=d91be69fde3995104e4827d77d5162d8757250d035b74525efccce98e892ed6200f9ea261e7e296827a6c5ad76d3b0686ca99d40ed5aa6600279a77e9a5c80b22f889c3fd74d83cba873 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55ac89364861faed9538fe931a2bf90878fa10072b3c5e520b733728948e1c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4a9308221816fe917b617d45c8a1f8bdb8adafec2bb9ab2f8bd6b1627bf9e1 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625487982e3421ad43f420890fc6fa445fbebaa29d42f83357832fb2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466581a3db6c8617d78b487458dfc00147b77d9a8f9d55d33fa54e9a099348118f9392dc0274cf7b028ba762c5bbe82c31d42ee5e297273ad7654acf25c798d67773c0bc7b485759cba4f41 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4f14513ce6f321d3e3cb4585286a18c666e6b3777ae346a7480f09dca7af55753d6822524406cfeee550f231c0b3a3b01127f4f272356b921ee0e01d4ae239d3eb7d8c357eee3630d1ac +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=53f77a183580b9f1fbcef4857976951cff9f90e21cca7a4fe7cddd5303b23f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25166ac4cc0f48a5e9a1af15f86c0a4b065a0c587aaadbcfb76ca98540431 + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c13c5b571263574d9b570c55e7e151b9425c1fe13510b467e0de +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c5c243ed69e6c32a5c5016b1b66676d6076aede0fd2df3c89b58f2df5a3ed2cf028f9a03a230cf08755d11147bd6ff8cfb9620d663d5ed048229b50d9724a4c96edcde2b208246ff5fad +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=77f77a124d513addd8faed07d38add6dc885d466a1f3f259847430780d121ac5b9097846c12a911d82fcc7a70dd5ae5901e3130a6fb48336ebc6f4d4504624ec357f34d47b896400dadb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd96a733132ce4bf0bb7f1fbffffd0e2cc805e2b2bc5b4c14684d1370e93fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73803758314e6aa57533c404442d54e9f3c6f94157c41d2d82cf608158473e + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547101213fa5a9485d131330b0dad493c48c4ae6e125226c1171f6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665239caf37bac645326193f36abf47c49b4568ab9ea3933a8dab0a835393c23e35235d08e2daad3a980adadad2fe14cc641a92e52f86d0316b33e490ee1569451313789c5c25b4bed70be +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=561aa523426011b76cd099db2c038f6405739eee844f4f59da33c6c315bebf27a86ff32a01f76e4dcfbe1cff50fa777dc99480af6b625530f264c850117ba858360c0d519c4a1ca747fa +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c188211012160a32e31359391f5d3bd9ebe2af466c2c3759d36d7f1b723a53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=330f1b1616e11def88c53fefeede6e62e5c89414516dc4f3eb55cc0a6dd244 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce80c6f31a908077340a4584cf6faa69c9d1076e89096c43a500 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eb1b0ba3208b9285c46d88de673268c0a9c11d1372df5c12348027d7b20d33e3f1dc618f2ee5f89bf2d6693b74596bf6ffa8d86d9c0976834a4b87c0a380495a89999ec6de2c885e64d4 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=6008678f2ef024bf48e09a421bfa274e0e134657e952b07b9628b88938f8489a42d6827d04601ecd23c946828baed03cb9ce7cabcf4646be4769f43bbf0e7bc04e369a6800d2b22856f9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f0fdc970b0edc1b34eff18de0753b76a4c407c63c75dfa31b7718a25bd9852 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=058345e46ccb2548fdff3835a49a67f7470b5e1d7c58b338e64ca4350b3bca + +handshake=Noise_XX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aaf8bd6d4f4015e5465aea27ce9bfe2f9cfeb1b38ee28d45032fe0b31e0ed19188c15754675bdf966090bf821a49f1578a512a2abb9c0aab546dbe471a5eafa8 +msg_2_payload= +msg_2_ciphertext=d91be69fde3995104e4827d77d5162d8757250d035b74525efccce98e892ed6266fdf087797c505e45b50a46d6c0bccc9fc689102189cf5dc55ddd007ae7ae95 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55ac89364861faed9538fe931a2bf90878fa10072b3c5e520b733728948e1c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4a9308221816fe917b617d45c8a1f8bdb8adafec2bb9ab2f8bd6b1627bf9e1 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c61a84f1a6f875a80930f90f6f24c98e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466581a3db6c8617d78b487458dfc00147b77d9a8f9d55d33fa54e9a099348118f95fdf6b5e53f9941c830ed2b01b858b1cae8d9a2026d27b784b650536adc06b0a +msg_2_payload= +msg_2_ciphertext=4f14513ce6f321d3e3cb4585286a18c666e6b3777ae346a7480f09dca7af55757f81040aaf7fa96ac14f973829c5f53b5c315baabb32d581cffff9457e8b9660 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=53f77a183580b9f1fbcef4857976951cff9f90e21cca7a4fe7cddd5303b23f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25166ac4cc0f48a5e9a1af15f86c0a4b065a0c587aaadbcfb76ca98540431 + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547d0b7163177636e07746a0985baa1bde +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c5c243ed69e6c32a5c5016b1b66676d6076aede0fd2df3c89b58f2df5a3ed2cf106bc5908bfbab97630dda6e089b6aabac42302aaa36328231a8f5ce210973f3 +msg_2_payload= +msg_2_ciphertext=77f77a124d513addd8faed07d38add6dc885d466a1f3f259847430780d121ac59d643454a8e9f7309150a019ecbd2c5eb6fd18674276f048feb2e80e0b428dd0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd96a733132ce4bf0bb7f1fbffffd0e2cc805e2b2bc5b4c14684d1370e93fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73803758314e6aa57533c404442d54e9f3c6f94157c41d2d82cf608158473e + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d3009e8a46eae769bf4bc5725b082568 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665239caf37bac645326193f36abf47c49b4568ab9ea3933a8dab0a835393c23e3a19c252ee839914581c912acd79e8b9d3e045cc120fa53182cd22a4b3ec551b4 +msg_2_payload= +msg_2_ciphertext=561aa523426011b76cd099db2c038f6405739eee844f4f59da33c6c315bebf2742413b1948478b5bf0a2331b765d1f5d93006650dec2aa4e51d16b0a4f9ed84f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c188211012160a32e31359391f5d3bd9ebe2af466c2c3759d36d7f1b723a53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=330f1b1616e11def88c53fefeede6e62e5c89414516dc4f3eb55cc0a6dd244 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7995d341b626e9de9e7b8f09441a8a7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eb1b0ba3208b9285c46d88de673268c0a9c11d1372df5c12348027d7b20d33e3b04a922618a0b8b1b247a4746b7b3d100cdb2fe21f40d48dbba03ef0fdeaee2b +msg_2_payload= +msg_2_ciphertext=6008678f2ef024bf48e09a421bfa274e0e134657e952b07b9628b88938f8489a810f13458ca37c4cf1ab45090357408af6d8938f5c1d45d9bc7b5c07665a6b4b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f0fdc970b0edc1b34eff18de0753b76a4c407c63c75dfa31b7718a25bd9852 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=058345e46ccb2548fdff3835a49a67f7470b5e1d7c58b338e64ca4350b3bca + +handshake=Noise_XX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aaf8bd6d4f4015e5465aea27ce9bfe2f9cfeb1b38ee28d45032fe0b31e0ed191ffc04dfc10ecd2efabbf30685693bcdcede85376a07ee6cffe47f51e2ae72a25058bc75b4b1293b32811 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=d91be69fde3995104e4827d77d5162d8757250d035b74525efccce98e892ed62c58bfde86a5512485175dec124b4c4ed6ca99d40ed5aa6600279bfbec5148741711eb6ad6fad14206c21 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=55ac89364861faed9538fe931a2bf90878fa10072b3c5e520b733728948e1c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4a9308221816fe917b617d45c8a1f8bdb8adafec2bb9ab2f8bd6b1627bf9e1 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625487982e3421ad43f420896f297a503188b235e25f5b56dcfd99ab +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466581a3db6c8617d78b487458dfc00147b77d9a8f9d55d33fa54e9a099348118f9521624cfc2d1ee318b7bce45260d590542ee5e297273ad7654ac556ccc7b6279a69733d6803d5b982594 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4f14513ce6f321d3e3cb4585286a18c666e6b3777ae346a7480f09dca7af5575a5f197a33764d3271cca1b3c345f51c31127f4f272356b921ee0a462f08c85c527b4e4935625e3fc88ff +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=53f77a183580b9f1fbcef4857976951cff9f90e21cca7a4fe7cddd5303b23f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25166ac4cc0f48a5e9a1af15f86c0a4b065a0c587aaadbcfb76ca98540431 + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c13c5b571263574d9b5726f56ea9aea8cc317511bfa8cf5e2e1f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c5c243ed69e6c32a5c5016b1b66676d6076aede0fd2df3c89b58f2df5a3ed2cfc938f3dab94aee2e67ff7d9e578192a2fb9620d663d5ed0482297f2455ba11c3289db6b3286384edc470 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=77f77a124d513addd8faed07d38add6dc885d466a1f3f259847430780d121ac51abfc6c6a39ce2c55a3b56fd63456b5901e3130a6fb48336ebc671ee2c5dde5da9dd4211c69d2a7c0347 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd96a733132ce4bf0bb7f1fbffffd0e2cc805e2b2bc5b4c14684d1370e93fe +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73803758314e6aa57533c404442d54e9f3c6f94157c41d2d82cf608158473e + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547101213fa5a9485d131331cc470c9c3a47b65d4dd9bfe832ccb8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665239caf37bac645326193f36abf47c49b4568ab9ea3933a8dab0a835393c23e3313ca4fa5c74e7a3f687a0d725e5db2641a92e52f86d0316b33e286176bad79badc46cb1e846e93a94f5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=561aa523426011b76cd099db2c038f6405739eee844f4f59da33c6c315bebf27e342e9ce2aa8d9d9b87f72a0cfa70c2ac99480af6b625530f264be548caae99ab6f8c4f6e199fb0faf40 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c188211012160a32e31359391f5d3bd9ebe2af466c2c3759d36d7f1b723a53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=330f1b1616e11def88c53fefeede6e62e5c89414516dc4f3eb55cc0a6dd244 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce80c6f31a908077340a967f7f3c97956cdff82835c308ff284f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eb1b0ba3208b9285c46d88de673268c0a9c11d1372df5c12348027d7b20d33e33ac38234778daf6c29e41aa50404fd91ffa8d86d9c0976834a4b8710815760185846df07e7ce9d95fa50 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=6008678f2ef024bf48e09a421bfa274e0e134657e952b07b9628b88938f8489ae12fc5cc1631fe08b8526b92f6348454b9ce7cabcf4646be47698ec1a10e0324a73b83e15a85d15ea053 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f0fdc970b0edc1b34eff18de0753b76a4c407c63c75dfa31b7718a25bd9852 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=058345e46ccb2548fdff3835a49a67f7470b5e1d7c58b338e64ca4350b3bca + +handshake=Noise_IX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466622476f6dc13fa05c82e29cf98e37d7c1e7aa9ea2ab7f341ba1db3e536ab9af93cc8bb3b47ed05ed3f678780e0294be50c0ed95f97a0ef014d45ef36ad2a6c5c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ee8c647ae002695d09b4ff7719085f820510f5a00c52e8b45b44a4a84d3689 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a1fd2b44a73bc70a207f970b6a6843e7247110f3be8d14a41507a506f03d63 + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625431e791109f10371f8305b72a88065b517025301ef523d9962d49201d5de6e03c8bc1c4d453575f9090a9070b8d2e27260315853452593e9bc82684a3f764a93b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c3a98ae9b8944c2e04b14098f75624c9649bc20d92b4fb9feb450c5adea13242b5e9e5187d7abe391fbc3a654f9042eeeaf3495b08b3450da47f9d5bded12a25 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96e8b979ac204a4c22fdb58e70f10a889d0ceb52a777e75376846e3e403903 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0d019e644bbdcc10bdc2443d0d12fd11a3d2122140ee3a01ef7c938726df92 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254074d28976125a685694f6e4d9f29f2dad768122fac65114c256e3280ff7fac212c40d51848089066523ed4026ecbf4e5ed14ca5590c1ed214fbfd90f0356ed13 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc1b623297e2182c3fc0e0c16f6799309650dd06e4b3e6004d30842f8fd46a1115a937ef532eecd9383d07a136a4177ef2ce37c2ed1d9f0ab601b1401b958217 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=16b0e85f7d29c70b5b3c6e087496d10c8b6f491eaf1d1a29d1988ab2d9a963 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=006069daef25a0d1b668145368fdd76e61a0aed53c7109f45bb6632b6155c7 + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254707384f2d1b60403d6983f48cdd2d54ef6d6201bd7b042556a09f4f21189e79550dec3d76dd8bb9657244ebc557e0fd1bff35cb50b8b64c9658a686404899b85 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b980bf81bae21ec3c711890b8af89330c505cb0a91b17caf3fd343fd318cb6010831177fec17f21da68af33d1d8c9909cd8236240afcd56f5f9d70f090b812f2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=387c61a76a79957e3f99d5dba4d89b098652201ea26220e961953955512f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81c3b9c80cd9d312e0208e596ffb917cc56971bab803eb6cfab729ddb91e01 + +handshake=Noise_IX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466622476f6dc13fa05c82e29cf98e37d7c1e7aa9ea2ab7f341ba1db3e536ab9af9d587c9ce59c0b5c278f67832116b7cc3863bdda85e4ea48d3401af232d6f738e3d27d3971c464ae019da +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ee8c647ae002695d09b4ff7719085f820510f5a00c52e8b45b44a4a84d3689 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a1fd2b44a73bc70a207f970b6a6843e7247110f3be8d14a41507a506f03d63 + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625431e791109f10371f8305b72a88065b517025301ef523d9962d49201d5de6e03c8bc1c4d453575f9090a9070b8d2e2726db0b7bef43ed75985760735cdb3ccf94f6799816a1bd407543c3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c3a98ae9b8944c2e04b14098f75624c9649bc20d92b4fb9feb450c5adea13242eef1dcae8547d04ec9cf15988accc82d4bee7c7f595716a7855c9e8e0dbd78e2baefbaa4ee1de38bf3a9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96e8b979ac204a4c22fdb58e70f10a889d0ceb52a777e75376846e3e403903 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0d019e644bbdcc10bdc2443d0d12fd11a3d2122140ee3a01ef7c938726df92 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254074d28976125a685694f6e4d9f29f2dad768122fac65114c256e3280ff7fac212c40d51848089066523ed4026ecbf4e5311f872ca6e591f4b57ca869841735ab09d7cff59de84efbcbfe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc1b623297e2182c3fc0e0c16f6799309650dd06e4b3e6004d30842f8fd46a1118b39882825db18d1a6f1e11c33189f75096fc90d3eb24eed3204a21588804fbf5bc658546c38809ebf2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=16b0e85f7d29c70b5b3c6e087496d10c8b6f491eaf1d1a29d1988ab2d9a963 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=006069daef25a0d1b668145368fdd76e61a0aed53c7109f45bb6632b6155c7 + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254707384f2d1b60403d6983f48cdd2d54ef6d6201bd7b042556a09f4f21189e79550dec3d76dd8bb9657244ebc557e0fd1abf9112523840039f52508eb47ad4896afc7ec7b61f0946286aa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b980bf81bae21ec3c711890b8af89330c505cb0a91b17caf3fd343fd318cb6019e547161afe678cea50333bd13f79208b80461c0e0c3d43a8780339640a33c5894699b57245fcab80c22 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=387c61a76a79957e3f99d5dba4d89b098652201ea26220e961953955512f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81c3b9c80cd9d312e0208e596ffb917cc56971bab803eb6cfab729ddb91e01 + +handshake=Noise_IX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466622476f6dc13fa05c82e29cf98e37d7c1e7aa9ea2ab7f341ba1db3e536ab9af930a67ac8e3f12fd042fcd87fedac96d10e9b513fce9dfa7034fa01b91e268d3b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ee8c647ae002695d09b4ff7719085f820510f5a00c52e8b45b44a4a84d3689 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a1fd2b44a73bc70a207f970b6a6843e7247110f3be8d14a41507a506f03d63 + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625431e791109f10371f8305b72a88065b517025301ef523d9962d49201d5de6e03c87375bdd6fe082a2538efee6d0aca07cf6da198785e60eb9eda10515d4de2c05 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c3a98ae9b8944c2e04b14098f75624c9649bc20d92b4fb9feb450c5adea13242cefd4fe51aee2d3e8a57497962d253f52fda8e4799e79cabd5b97126107f51ef +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96e8b979ac204a4c22fdb58e70f10a889d0ceb52a777e75376846e3e403903 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0d019e644bbdcc10bdc2443d0d12fd11a3d2122140ee3a01ef7c938726df92 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254074d28976125a685694f6e4d9f29f2dad768122fac65114c256e3280ff7fac212288a529637006c9cdf63983295b55d008a5b13d51883b6d510ce07db1e0ab29 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc1b623297e2182c3fc0e0c16f6799309650dd06e4b3e6004d30842f8fd46a11ac55526f15c640cf8454ba6f133edbefea975b2d2a2cf13d43c07b29046905a0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=16b0e85f7d29c70b5b3c6e087496d10c8b6f491eaf1d1a29d1988ab2d9a963 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=006069daef25a0d1b668145368fdd76e61a0aed53c7109f45bb6632b6155c7 + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254707384f2d1b60403d6983f48cdd2d54ef6d6201bd7b042556a09f4f21189e795a4d70b030812e4f3c7df3faff6cf7997ce1cf5b41dc8f39c10f7a6c8160325ba +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b980bf81bae21ec3c711890b8af89330c505cb0a91b17caf3fd343fd318cb601ce71053a753dc4a395c38bee2f9c65d9371aac75c9b11cd59c3d9c8040cc8c1a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=387c61a76a79957e3f99d5dba4d89b098652201ea26220e961953955512f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81c3b9c80cd9d312e0208e596ffb917cc56971bab803eb6cfab729ddb91e01 + +handshake=Noise_IX_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466622476f6dc13fa05c82e29cf98e37d7c1e7aa9ea2ab7f341ba1db3e536ab9af9cf8d0caf69ea6d6d9fe863f135d765dc863bdda85e4ea48d340128833ce0029b5e80c4902e07ca963cc6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ee8c647ae002695d09b4ff7719085f820510f5a00c52e8b45b44a4a84d3689 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a1fd2b44a73bc70a207f970b6a6843e7247110f3be8d14a41507a506f03d63 + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625431e791109f10371f8305b72a88065b517025301ef523d9962d49201d5de6e03c87375bdd6fe082a2538efee6d0aca07cdb0b7bef43ed759857605b1c8a4434514ba7ff980a94999f767b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c3a98ae9b8944c2e04b14098f75624c9649bc20d92b4fb9feb450c5adea132421dff6426674f95b9cca665bf38c8a2664bee7c7f595716a7855ce3a01c256df89227a7f03ae351c54d1c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96e8b979ac204a4c22fdb58e70f10a889d0ceb52a777e75376846e3e403903 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0d019e644bbdcc10bdc2443d0d12fd11a3d2122140ee3a01ef7c938726df92 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254074d28976125a685694f6e4d9f29f2dad768122fac65114c256e3280ff7fac212288a529637006c9cdf63983295b55d0311f872ca6e591f4b57cc52c513c2541cad183c73557e8de3884 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc1b623297e2182c3fc0e0c16f6799309650dd06e4b3e6004d30842f8fd46a1165270d8bc779d74b6158d1ad0382aeab5096fc90d3eb24eed320925d70db3a28b6913b2184f99d534c83 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=16b0e85f7d29c70b5b3c6e087496d10c8b6f491eaf1d1a29d1988ab2d9a963 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=006069daef25a0d1b668145368fdd76e61a0aed53c7109f45bb6632b6155c7 + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254707384f2d1b60403d6983f48cdd2d54ef6d6201bd7b042556a09f4f21189e795a4d70b030812e4f3c7df3faff6cf7997abf9112523840039f525ad5950e38bc095c149086d5a40ae31ef +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b980bf81bae21ec3c711890b8af89330c505cb0a91b17caf3fd343fd318cb60191ee54eae17fa342a351b1b09dce4265b80461c0e0c3d43a87803fd715ab4c27017bb4cf345588a80109 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=387c61a76a79957e3f99d5dba4d89b098652201ea26220e961953955512f27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81c3b9c80cd9d312e0208e596ffb917cc56971bab803eb6cfab729ddb91e01 + +handshake=Noise_N_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6359a5d6c7a1d170a912f5fe2c9edca +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f5bf9f4283f184acb247e55708b728b70ec83427200de1900a41e685e7f2c2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ebe3aeca2bc09cd4f4168e8a33186aace3fca9d05ec0380c258e4124a8ae01 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625438817726d5cb633f2f7039e327d8d659 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bb3c765be9629a576747028e7a7916e1a4b30ebf768c5417e431bfd32aceb7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4f792448e97c8c5cbc0ddbc2f6df569f02a6de080d72d9e766c2cae2706e45 + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6e56e8d7384aa396e1e8a0517e02a6c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=91363a8183aa963e9d8e2ffbb446e41caf9a089628b68726b35ec8a9ea65f5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a72d808b3ec5344cabf496ba6c02af8caff4b518b8d7c37a03dd69e560baf0 + +handshake=Noise_N_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa097823bab1ebd1506811991b670155aa82a4cd8b4bbe761b5c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f5bf9f4283f184acb247e55708b728b70ec83427200de1900a41e685e7f2c2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ebe3aeca2bc09cd4f4168e8a33186aace3fca9d05ec0380c258e4124a8ae01 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625484649fcef92dec96507574eb9cec727f5f7da8ff6886fd70ac2c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bb3c765be9629a576747028e7a7916e1a4b30ebf768c5417e431bfd32aceb7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4f792448e97c8c5cbc0ddbc2f6df569f02a6de080d72d9e766c2cae2706e45 + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254be7a2d6947cc9358be204acc063aea95100411f5fd0cc3985b3d +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=91363a8183aa963e9d8e2ffbb446e41caf9a089628b68726b35ec8a9ea65f5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a72d808b3ec5344cabf496ba6c02af8caff4b518b8d7c37a03dd69e560baf0 + +handshake=Noise_N_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549430a045cd2d4d6811150b99292daae4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f5bf9f4283f184acb247e55708b728b70ec83427200de1900a41e685e7f2c2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ebe3aeca2bc09cd4f4168e8a33186aace3fca9d05ec0380c258e4124a8ae01 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540ac0e3d45b1948f681e1682ebee5dd45 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bb3c765be9629a576747028e7a7916e1a4b30ebf768c5417e431bfd32aceb7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4f792448e97c8c5cbc0ddbc2f6df569f02a6de080d72d9e766c2cae2706e45 + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541ec9db97d69c252fc8f8742e0f4a7e1e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=91363a8183aa963e9d8e2ffbb446e41caf9a089628b68726b35ec8a9ea65f5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a72d808b3ec5344cabf496ba6c02af8caff4b518b8d7c37a03dd69e560baf0 + +handshake=Noise_N_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa097823bab1ebd15068f4572f11b906f0509166173a6e4a6273 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=f5bf9f4283f184acb247e55708b728b70ec83427200de1900a41e685e7f2c2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ebe3aeca2bc09cd4f4168e8a33186aace3fca9d05ec0380c258e4124a8ae01 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625484649fcef92dec965075fe2be8f7e95575f16fc60eda06edfe27 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bb3c765be9629a576747028e7a7916e1a4b30ebf768c5417e431bfd32aceb7 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4f792448e97c8c5cbc0ddbc2f6df569f02a6de080d72d9e766c2cae2706e45 + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254be7a2d6947cc9358be205a810af7eb9e663eea8ecfec02cb8641 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=91363a8183aa963e9d8e2ffbb446e41caf9a089628b68726b35ec8a9ea65f5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a72d808b3ec5344cabf496ba6c02af8caff4b518b8d7c37a03dd69e560baf0 + +handshake=Noise_K_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f6065d2dbb9baa86605ebf7b6c743a9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=46685f7f48e63d44f5cd878e8344a49e8cb366489ceaf4a3665f7e50be6658 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=67b542a893449da5c0d811252a061e86d78e6f38e8dfd6ea91758c5efee3cb + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce3f329cc91477035bf61c0cdc30e80b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=606a2840cc2a7cc01e93500ddd06b165aa23af8f31fb02968ea815ff4be3de +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9a68c42768a4e608ffc81120222f6b93950d5c7af8438e81fc6422c1f6de6a + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254063e3bccc72c13cd3469bb230e1384c2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c1c4aaf379d5ba311247236fd68665336ab954fefc742cc9151032b2a5639f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=d94fcde08550aa28096d526b2054a32f79a9232837b2a9596e8b1054f680b9 + +handshake=Noise_K_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bcc436a2edb74613f5e73ff0cbfda5cb0e6cc1eb2164829c4d34 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=46685f7f48e63d44f5cd878e8344a49e8cb366489ceaf4a3665f7e50be6658 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=67b542a893449da5c0d811252a061e86d78e6f38e8dfd6ea91758c5efee3cb + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254565f2ca67c2a0bd9e036531691ac9362bc81d923f9384405fd05 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=606a2840cc2a7cc01e93500ddd06b165aa23af8f31fb02968ea815ff4be3de +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9a68c42768a4e608ffc81120222f6b93950d5c7af8438e81fc6422c1f6de6a + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254eb8d7c30c00e0fae542623b3ed495873dcc8fc25596a3c04aa5c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c1c4aaf379d5ba311247236fd68665336ab954fefc742cc9151032b2a5639f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=d94fcde08550aa28096d526b2054a32f79a9232837b2a9596e8b1054f680b9 + +handshake=Noise_K_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d40e94b2d13927059aa1e609ffd168e3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=46685f7f48e63d44f5cd878e8344a49e8cb366489ceaf4a3665f7e50be6658 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=67b542a893449da5c0d811252a061e86d78e6f38e8dfd6ea91758c5efee3cb + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f091ca3d19682d9ec8aa47bae87c888 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=606a2840cc2a7cc01e93500ddd06b165aa23af8f31fb02968ea815ff4be3de +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9a68c42768a4e608ffc81120222f6b93950d5c7af8438e81fc6422c1f6de6a + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542cc66e189a62c266ec1d89ab60e6e640 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c1c4aaf379d5ba311247236fd68665336ab954fefc742cc9151032b2a5639f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=d94fcde08550aa28096d526b2054a32f79a9232837b2a9596e8b1054f680b9 + +handshake=Noise_K_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bcc436a2edb74613f5e745b38fa18699422bcccdcd0af79b7e35 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=46685f7f48e63d44f5cd878e8344a49e8cb366489ceaf4a3665f7e50be6658 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=67b542a893449da5c0d811252a061e86d78e6f38e8dfd6ea91758c5efee3cb + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254565f2ca67c2a0bd9e036467bf9073d8c7351ac13f4798b62a054 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=606a2840cc2a7cc01e93500ddd06b165aa23af8f31fb02968ea815ff4be3de +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9a68c42768a4e608ffc81120222f6b93950d5c7af8438e81fc6422c1f6de6a + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254eb8d7c30c00e0fae54265f2bff17b2e288bfccc3bb76c742beb0 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c1c4aaf379d5ba311247236fd68665336ab954fefc742cc9151032b2a5639f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=d94fcde08550aa28096d526b2054a32f79a9232837b2a9596e8b1054f680b9 + +handshake=Noise_X_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae50825004becfffe1a179be72c6e15ccc2c72727385ce02b8235b081e61aa049e281d25a75a66c83a48e736491cbb7044ddf558abb9fcaaf6157619f41dff9f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1948e447f76f5337534c280ebd220db961d6ebb9bd12db223de7528605c36f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=135cfc52de19616945aa2ad6c5cc04849608eafee2ff4222c013aa0b23dc33 + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7375b5a510999c4b39fda0567b848eb149f5699752369183239db664fa14e63e9a9b61dd5971684104852bf16a5d13947ea7f52a91ebb7e98b1462f76bbab87 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0f71c21b1edfb5eedb2f0bf2afc333854ad3b88d85bdb1dcbabc200c86adca +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=484530df1518ec3798f235162c2d8d98c40bb8896cf863debc51f1ea53b76b + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f3b3c704067dc33efce5bd9217dddd65a82aee230acfd966320c92d40c5f1fe596e9b54f6f0847c5c9f5e06f542c0a8332ae17acafabae272de40b560072b9cc +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7f8089c4143e918f5755a613565b3412da583f1d1e45d1eb0b0162ae75aed8 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=6f73460c11922e7f77b5661ddcc7bc4e6bd7d8749cd2181aa6c99d5b5e20fe + +handshake=Noise_X_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae50825004becfffe1a179be72c6e15ccc2c72727385ce02b8235b081e61aa049e281d25a75a66c83a48e736491cbb70d04b408e4e1b9f2f0dd80ae2871d7857bc4d057f3fb66808c320 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1948e447f76f5337534c280ebd220db961d6ebb9bd12db223de7528605c36f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=135cfc52de19616945aa2ad6c5cc04849608eafee2ff4222c013aa0b23dc33 + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7375b5a510999c4b39fda0567b848eb149f5699752369183239db664fa14e63e9a9b61dd5971684104852bf16a5d139025417449f82c85ee89977abd0d750fe80c47e9b228ed26e5c7c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0f71c21b1edfb5eedb2f0bf2afc333854ad3b88d85bdb1dcbabc200c86adca +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=484530df1518ec3798f235162c2d8d98c40bb8896cf863debc51f1ea53b76b + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f3b3c704067dc33efce5bd9217dddd65a82aee230acfd966320c92d40c5f1fe596e9b54f6f0847c5c9f5e06f542c0a838469063891941b5b191c47ee925457eb3c054db3c14f48666732 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7f8089c4143e918f5755a613565b3412da583f1d1e45d1eb0b0162ae75aed8 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=6f73460c11922e7f77b5661ddcc7bc4e6bd7d8749cd2181aa6c99d5b5e20fe + +handshake=Noise_X_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae50825004becfffe1a179be72c6e15ccc2c72727385ce02b8235b081e61aa04279392a66a24958e4c789de27a5a0e99960ea42aafb2efaf1f6062a89b3ac3bd +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1948e447f76f5337534c280ebd220db961d6ebb9bd12db223de7528605c36f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=135cfc52de19616945aa2ad6c5cc04849608eafee2ff4222c013aa0b23dc33 + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7375b5a510999c4b39fda0567b848eb149f5699752369183239db664fa14e63302f42f2022e000bdbfc75716f88b8221e6e2aefeffac88f8436a601947a28aa +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0f71c21b1edfb5eedb2f0bf2afc333854ad3b88d85bdb1dcbabc200c86adca +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=484530df1518ec3798f235162c2d8d98c40bb8896cf863debc51f1ea53b76b + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f3b3c704067dc33efce5bd9217dddd65a82aee230acfd966320c92d40c5f1fe59c14457d6a0815656bce5597e12c212ddea7c3b7f9ad5802e672eff6e7aaf628 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7f8089c4143e918f5755a613565b3412da583f1d1e45d1eb0b0162ae75aed8 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=6f73460c11922e7f77b5661ddcc7bc4e6bd7d8749cd2181aa6c99d5b5e20fe + +handshake=Noise_X_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae50825004becfffe1a179be72c6e15ccc2c72727385ce02b8235b081e61aa04279392a66a24958e4c789de27a5a0e99d04b408e4e1b9f2f0dd8b324d4802cfb3c954c58df50ce19a54c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1948e447f76f5337534c280ebd220db961d6ebb9bd12db223de7528605c36f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=135cfc52de19616945aa2ad6c5cc04849608eafee2ff4222c013aa0b23dc33 + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7375b5a510999c4b39fda0567b848eb149f5699752369183239db664fa14e63302f42f2022e000bdbfc75716f88b822025417449f82c85ee8999a9d0502c5154f52f57239a43338ebd2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0f71c21b1edfb5eedb2f0bf2afc333854ad3b88d85bdb1dcbabc200c86adca +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=484530df1518ec3798f235162c2d8d98c40bb8896cf863debc51f1ea53b76b + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f3b3c704067dc33efce5bd9217dddd65a82aee230acfd966320c92d40c5f1fe59c14457d6a0815656bce5597e12c212d8469063891941b5b191cfce15fda4e83fcf8fb9065f9c55e22fc +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=7f8089c4143e918f5755a613565b3412da583f1d1e45d1eb0b0162ae75aed8 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=6f73460c11922e7f77b5661ddcc7bc4e6bd7d8749cd2181aa6c99d5b5e20fe + +handshake=Noise_NN_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846683a0dd518c7d9a09bc8500bc2e868187 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0909e697fc6dca9ffceffebee77c39187c353d4256d66f6d42ff5d6a8b5bcd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0770576631856631b449818953d4252baf1cf8d49d718ce220b9173567fc97 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541535fb045bd97504725efe47351fd5d8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e0bd9f3000f0f276e99bdc78a91a30ca +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7bb01e54840881ef4911b030602c665e4799652c4260b32f67119716cf2dac +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=63c4c131b3c079eb101cf9cd03627e5d50e693513402efb26d5f46d62ba1e0 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254febbb98d9ec54939c9cd08f15df12c9d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a233b33fe34e7a3cf0d34cc475ced00d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8617a57d1a212d915a093ba691465321b3a5e83a2a09334bc17a66e07f340b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bbddd9a51a1fe99634ea09790bfab387047c0bee2b540cbaa009e4b33f547d + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542383ccc8749a96890523a8c5c90c3b3a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846620c5d7fc3e102d94a2bcab25721f32c4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a924b18a801dad51bf702aa50f87d8f3e2d3e54cb76c94493f5305768f5f64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c94546ec021695355755f7e82ce1a12679f8df2d5a5b6e533c4cdc645a5f9 + +handshake=Noise_NN_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846626cb189266923cb8ce8e4c5203887255b709071d34ae3fb80274 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0909e697fc6dca9ffceffebee77c39187c353d4256d66f6d42ff5d6a8b5bcd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0770576631856631b449818953d4252baf1cf8d49d718ce220b9173567fc97 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625499813d4f7cdbccb39053e17bb5fcb237d3308481578cdf766e14 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665a507bc4cb8222edadcbb119a863c7e86363718152651d0ce152 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7bb01e54840881ef4911b030602c665e4799652c4260b32f67119716cf2dac +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=63c4c131b3c079eb101cf9cd03627e5d50e693513402efb26d5f46d62ba1e0 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254294dfe9247d7b2223638cfbb18fa8d5f4fca0215e7d473ee39aa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846638d4e172b074863b2c8ec44bba6907b80112d0d2358b4abb6e55 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8617a57d1a212d915a093ba691465321b3a5e83a2a09334bc17a66e07f340b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bbddd9a51a1fe99634ea09790bfab387047c0bee2b540cbaa009e4b33f547d + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541b462c2b118f585719b4c4853b82356500feb45573d40dfdd474 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664f09893c38c139765e44808080e1dacdc75c32e596a79f72f0ee +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a924b18a801dad51bf702aa50f87d8f3e2d3e54cb76c94493f5305768f5f64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c94546ec021695355755f7e82ce1a12679f8df2d5a5b6e533c4cdc645a5f9 + +handshake=Noise_NN_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c70a91b5ce390b4d2002c46c6e2a3248 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0909e697fc6dca9ffceffebee77c39187c353d4256d66f6d42ff5d6a8b5bcd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0770576631856631b449818953d4252baf1cf8d49d718ce220b9173567fc97 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a5fa9343b5a5a66947027412f3520c9b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ba0d0f5cf7fc7257567f2f27c2fd627 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7bb01e54840881ef4911b030602c665e4799652c4260b32f67119716cf2dac +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=63c4c131b3c079eb101cf9cd03627e5d50e693513402efb26d5f46d62ba1e0 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cedfcc8eac13a24e1e689e3cfc7baf62 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d387cd8664f5037d39aac8746ccd06b9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8617a57d1a212d915a093ba691465321b3a5e83a2a09334bc17a66e07f340b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bbddd9a51a1fe99634ea09790bfab387047c0bee2b540cbaa009e4b33f547d + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540ec56f5161a8755374b1848c641eddc3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466478d9b9fb165b8eb3f4b6718e1f1e245 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a924b18a801dad51bf702aa50f87d8f3e2d3e54cb76c94493f5305768f5f64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c94546ec021695355755f7e82ce1a12679f8df2d5a5b6e533c4cdc645a5f9 + +handshake=Noise_NN_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846626cb189266923cb8ce8e3fc80aa75d92678f6bfe13be7ff6aed1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0909e697fc6dca9ffceffebee77c39187c353d4256d66f6d42ff5d6a8b5bcd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0770576631856631b449818953d4252baf1cf8d49d718ce220b9173567fc97 + +handshake=Noise_NNpsk0_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625499813d4f7cdbccb39053c90fa0232673ba28f11c1e925324c845 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665a507bc4cb8222edadcb8a3c7dd94841834ec807680c5446d280 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7bb01e54840881ef4911b030602c665e4799652c4260b32f67119716cf2dac +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=63c4c131b3c079eb101cf9cd03627e5d50e693513402efb26d5f46d62ba1e0 + +handshake=Noise_NNpsk1_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254294dfe9247d7b2223638957faf2dd1bd18941b394140015d37ed +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846638d4e172b074863b2c8e80ee9b319d2677512167577c8d105ecb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8617a57d1a212d915a093ba691465321b3a5e83a2a09334bc17a66e07f340b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bbddd9a51a1fe99634ea09790bfab387047c0bee2b540cbaa009e4b33f547d + +handshake=Noise_NNpsk2_25519_AESGCM_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541b462c2b118f585719b4d2c84f08adfde3c8f24735ec8df3c5d7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664f09893c38c139765e44f2d6a49210f05ada099fb05937f7aa5b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a924b18a801dad51bf702aa50f87d8f3e2d3e54cb76c94493f5305768f5f64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c94546ec021695355755f7e82ce1a12679f8df2d5a5b6e533c4cdc645a5f9 + +handshake=Noise_KN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846664441190c10b03429a717dd68392cbc8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6e0b143fbe681fc040a0a32845a6766583a5b8b4615d43ef71a3345aa54e0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8dc5ed06a9e9017a62f1aa3a25421a3264272044251bd7ac02e849872891ae + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a3c3f95a1f27a264236e3ef44c8e4dde +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466facb3853ea6a08b4de16f555048fa04b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bc4c502252e5db42ab745807e689b501dddc0840bd276eb455d6ea1b6a9d8a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cdd0dea469b39b46374e168adb6948bc0ec1b132381214394dd3d98d4e7c3 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545926fa51ad53d91b7a4f033a897a8930 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661cb9f7cae8dc0045a8d861c5ddfa6aef +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3af9773fcd5a612c186cf94c7b5e3d008c40d036be9227cf8f90a90bf59cdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60f7a4448202b3535ab559b4a2b28583bf8475c4858b16e4460733a3b44bef + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625401d487a4cde829a7e46047baadfa8d75 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ed06a23fee4f0d95820c4e1f3cbea303 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=415377cf4fe494b8bad397ec42f85401f9a11edfd752e6aaa30a5951e8c5b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9562176c1eb69374a4186d61cda01ec132b826ae9e1644869a1fd5c93fde04 + +handshake=Noise_KN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846678409b14b108da18bef6fbe76cd430200b471f2df5b968638a83 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6e0b143fbe681fc040a0a32845a6766583a5b8b4615d43ef71a3345aa54e0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8dc5ed06a9e9017a62f1aa3a25421a3264272044251bd7ac02e849872891ae + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ac9a08aee31a00906e2c62ee6d06c88657479d8e51978da1bf21 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d46bd6b98eb3ca668bacae3ee77e683c19ca06381ae1ac2f32ff +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bc4c502252e5db42ab745807e689b501dddc0840bd276eb455d6ea1b6a9d8a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cdd0dea469b39b46374e168adb6948bc0ec1b132381214394dd3d98d4e7c3 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f29b85c3ab64ada6747a6dab2e1e7a4cd26cdc28eb5a00cc1083 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661ea48045213d2c8ac201ebab565e2df47e1a3e5fa9c13c674bff +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3af9773fcd5a612c186cf94c7b5e3d008c40d036be9227cf8f90a90bf59cdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60f7a4448202b3535ab559b4a2b28583bf8475c4858b16e4460733a3b44bef + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c5328cfba6436415d31dd4d5a50775cff355cb2d891dbbbf2af5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466325031532f718417152caa21e8709f94486d527f4c2b946ebacd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=415377cf4fe494b8bad397ec42f85401f9a11edfd752e6aaa30a5951e8c5b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9562176c1eb69374a4186d61cda01ec132b826ae9e1644869a1fd5c93fde04 + +handshake=Noise_KN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe09eb752d902e72e41d1b0daeb64844 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6e0b143fbe681fc040a0a32845a6766583a5b8b4615d43ef71a3345aa54e0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8dc5ed06a9e9017a62f1aa3a25421a3264272044251bd7ac02e849872891ae + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540776f384d8dcbb0929c9ee5b13e3f0bd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846689bd16f0e54d870dcbf293d64cb12ec5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bc4c502252e5db42ab745807e689b501dddc0840bd276eb455d6ea1b6a9d8a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cdd0dea469b39b46374e168adb6948bc0ec1b132381214394dd3d98d4e7c3 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625417510ed9f5b0c12079db76a8aa285424 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c716e009a9464a48d138b46f035805e0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3af9773fcd5a612c186cf94c7b5e3d008c40d036be9227cf8f90a90bf59cdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60f7a4448202b3535ab559b4a2b28583bf8475c4858b16e4460733a3b44bef + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c32a9ede6e1cbd9b00610e80d2fdb2ea +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662d90cba0b594c0e4e0a7c96bb616f298 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=415377cf4fe494b8bad397ec42f85401f9a11edfd752e6aaa30a5951e8c5b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9562176c1eb69374a4186d61cda01ec132b826ae9e1644869a1fd5c93fde04 + +handshake=Noise_KN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846678409b14b108da18bef6fc2974baa4e86c3595efbe635b98b3e2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6e0b143fbe681fc040a0a32845a6766583a5b8b4615d43ef71a3345aa54e0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8dc5ed06a9e9017a62f1aa3a25421a3264272044251bd7ac02e849872891ae + +handshake=Noise_KNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ac9a08aee31a00906e2c8929167672a0faf33aacb6f2e727797f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d46bd6b98eb3ca668bacb80eebd706c1b753a568ab393636daef +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bc4c502252e5db42ab745807e689b501dddc0840bd276eb455d6ea1b6a9d8a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cdd0dea469b39b46374e168adb6948bc0ec1b132381214394dd3d98d4e7c3 + +handshake=Noise_KNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f29b85c3ab64ada6747a071c3c7927ef1c434aa4b4269d189234 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661ea48045213d2c8ac201e6357b0a142b0804024efe755a596501 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3af9773fcd5a612c186cf94c7b5e3d008c40d036be9227cf8f90a90bf59cdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=60f7a4448202b3535ab559b4a2b28583bf8475c4858b16e4460733a3b44bef + +handshake=Noise_KNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c5328cfba6436415d31d40a72370f1f0b6ac748bae773d61cf5f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466325031532f718417152cd4e5e44d98111867943972554a320228 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=415377cf4fe494b8bad397ec42f85401f9a11edfd752e6aaa30a5951e8c5b4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9562176c1eb69374a4186d61cda01ec132b826ae9e1644869a1fd5c93fde04 + +handshake=Noise_NK_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540aca6f817356230937ac107dff4a8f06 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ad767eba25b2c944082016459215cb2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6f4e53c8e82abdc1877317ee614b2cf1c36694a48536e932f5d5970709c23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d08651c70754decf41c8b79d1fe8e8da60cdf64cbb521ab1f5be171617988 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546e8a8ab143d0babd5bb2974dfd62d421 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fa53f63f7b00b20da8a8a24a249b8d00 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e73eb987000909cc3ce02566091760e69f524f23372277fbd94d2b335ee020 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0e503113b6f99ce899fee344347bcc59165d827f4982c9a0af6f53c45608ce + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625467403733097e5ba8c0684832b42d212b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663c43292db7e2a865604940ab900ec307 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f3415ea0c9132c69c06f29873d9192a0910a6763addfc4e306b13c4e06c57c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c61e0bcc08bc9e2571eabbd48f192ecc3e846463f3b05c4cae6ffa956dce72 + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f00172caeafa67f00bcf4b6a286d653c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe2a80ce5f664bdeef527317284ef4b6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ed4dfff4fbbf57c63acf124128f12d3323706cd4212796f13ba3391f83e249 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8009206bac08e514df2c83e3238bf92c5dc209430cbecb936b1a93813de1dc + +handshake=Noise_NK_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bdf08b60ecbebcc2f5068183649b76c2cc2674fd4d580911729d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dacd38c1ad625caa0a4720445c6ac87f16e4b09d8a27489483fa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6f4e53c8e82abdc1877317ee614b2cf1c36694a48536e932f5d5970709c23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d08651c70754decf41c8b79d1fe8e8da60cdf64cbb521ab1f5be171617988 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548bf52c4caaaaacfe7a715566f9652044280280d56a5301e3d4f7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846694cf846b0941f8f8a46354a686838fa6efbeff8490cd3279ce6e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e73eb987000909cc3ce02566091760e69f524f23372277fbd94d2b335ee020 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0e503113b6f99ce899fee344347bcc59165d827f4982c9a0af6f53c45608ce + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437ad3a66b77c777309c59e3ffb70fdaaa1998f0ea6a7fea4aaf7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e4888b3081c3c5f198244d6a8245e8cbe0d843b4885374b5823 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f3415ea0c9132c69c06f29873d9192a0910a6763addfc4e306b13c4e06c57c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c61e0bcc08bc9e2571eabbd48f192ecc3e846463f3b05c4cae6ffa956dce72 + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546f881ee2ccd20f3d6a748ee7bd31867d252abc83c3a2e810bc01 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cc2683e6a737d2a339a6de63b341afc6e6da4f2e6acc295ba0c5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ed4dfff4fbbf57c63acf124128f12d3323706cd4212796f13ba3391f83e249 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8009206bac08e514df2c83e3238bf92c5dc209430cbecb936b1a93813de1dc + +handshake=Noise_NK_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625418771dd05bb254570cd36afecdd1f06b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cc535116cff2a6e84875769de7d118fa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6f4e53c8e82abdc1877317ee614b2cf1c36694a48536e932f5d5970709c23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d08651c70754decf41c8b79d1fe8e8da60cdf64cbb521ab1f5be171617988 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254235c1295c64674e9d24b1ac8387ceff0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f95d8632a153e1ba48ba7c604ac95c2c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e73eb987000909cc3ce02566091760e69f524f23372277fbd94d2b335ee020 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0e503113b6f99ce899fee344347bcc59165d827f4982c9a0af6f53c45608ce + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547bb352c4574bffe38b6f2fd437245349 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b4d595560f6d4bab34135d6d5f0e95b9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f3415ea0c9132c69c06f29873d9192a0910a6763addfc4e306b13c4e06c57c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c61e0bcc08bc9e2571eabbd48f192ecc3e846463f3b05c4cae6ffa956dce72 + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625412175e79501bbdb8f9c34f832d70faf5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660faec0e7d65e6e02e540a12f372524de +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ed4dfff4fbbf57c63acf124128f12d3323706cd4212796f13ba3391f83e249 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8009206bac08e514df2c83e3238bf92c5dc209430cbecb936b1a93813de1dc + +handshake=Noise_NK_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bdf08b60ecbebcc2f5066ba2dc101956c40473b8c6dfbc24f58b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dacd38c1ad625caa0a4702d85babf3841256b5660d3228dc121c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6f4e53c8e82abdc1877317ee614b2cf1c36694a48536e932f5d5970709c23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d08651c70754decf41c8b79d1fe8e8da60cdf64cbb521ab1f5be171617988 + +handshake=Noise_NKpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548bf52c4caaaaacfe7a71f5e1496c23adbee3020d4eb45211637a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846694cf846b0941f8f8a463cfc791d89367bcce3320c4f0460a91b9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e73eb987000909cc3ce02566091760e69f524f23372277fbd94d2b335ee020 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0e503113b6f99ce899fee344347bcc59165d827f4982c9a0af6f53c45608ce + +handshake=Noise_NKpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437ad3a66b77c777309c5d7683c6082c82b5adb434c70325029cc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e4888b3081c3c5f1982d5856d4940dbdd17c07b285e331dce60 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f3415ea0c9132c69c06f29873d9192a0910a6763addfc4e306b13c4e06c57c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c61e0bcc08bc9e2571eabbd48f192ecc3e846463f3b05c4cae6ffa956dce72 + +handshake=Noise_NKpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546f881ee2ccd20f3d6a74cad4c7694924e6494b10399373d97cd1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cc2683e6a737d2a339a62c5b55ccd5da93091e0295f94ae259b7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ed4dfff4fbbf57c63acf124128f12d3323706cd4212796f13ba3391f83e249 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8009206bac08e514df2c83e3238bf92c5dc209430cbecb936b1a93813de1dc + +handshake=Noise_KK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544cfcee5c7fcaf9d598c33703fd0c2776 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665e6949aaa57066895baf7ab83e004ae5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=31f8fb1587255c4b0dd700a9b6c8f43f8a784c2b182fd9c90e236708314b5d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e536a299bf11d6abe9d3a94183d029f1eb3e12e11b3dab41e21789869dcc93 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549b23f41fd589eccd4f092f268f28d26b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846660c9d890cdde369d3d997ed453e687da +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=91e44c0d5d9cd28abf7c8b30bb2e3d0550239b9e17953d9f089ec3d930df27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2e741b2768bfd0bbfeda04cbd22add5afa67b677a3b01af28dbaf63159b9bc + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a0c920d6078d924f12ff949a21dc7538 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846682eb33bc6a6c88a84d4dc18a5d637337 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d95cc1c999c97bbeedd5c7ec4652084d4b62a16f82500d755aa618eb4a53e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=868d5fcee2fc24e0449b05781857718f8a52fa5c7e3e91e31835579480126c + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542c378d98d2cbcf1bd35e56b9dc028451 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466222d4ef8c802a217923cc92c7d12ff70 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe234b7f281411b7c6b3d7b75466259f4e5f05c12ba78c04f44432f0fba361 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9e35422ab4388dd10073b1a0ef26ad00041372fdf968809e67f56f1b6ef723 + +handshake=Noise_KK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b607e12f23e87019e6edd5ff907e3244c4faabde9dd7f413268 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f550ee88c31bb77034f6b25459148fe70370546a6e427b27260 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=31f8fb1587255c4b0dd700a9b6c8f43f8a784c2b182fd9c90e236708314b5d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e536a299bf11d6abe9d3a94183d029f1eb3e12e11b3dab41e21789869dcc93 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aa72dba4eb5155d2465ab23ff1c5f93b23534b5f3e4af45250fd +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846662d579964a47442efacbe7a4d3d39194eeb4b540be23480bad21 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=91e44c0d5d9cd28abf7c8b30bb2e3d0550239b9e17953d9f089ec3d930df27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2e741b2768bfd0bbfeda04cbd22add5afa67b677a3b01af28dbaf63159b9bc + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549e185b6bf0ab96577514a994636c9f591469389a01313efd8bd2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466678170eb78b10bba2423cc2a8177294aae0ef03d0baaf925d9d7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d95cc1c999c97bbeedd5c7ec4652084d4b62a16f82500d755aa618eb4a53e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=868d5fcee2fc24e0449b05781857718f8a52fa5c7e3e91e31835579480126c + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254669c71c550b8a43b3435e62f9eb9a7e2b5b4ee7736ec81cd5b48 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466728e2a0d6eeceaee629ad6b31058960aaf8a1c97905808a811a4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe234b7f281411b7c6b3d7b75466259f4e5f05c12ba78c04f44432f0fba361 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9e35422ab4388dd10073b1a0ef26ad00041372fdf968809e67f56f1b6ef723 + +handshake=Noise_KK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254287c6242f3601fc5c1bb6fcb4624c2c7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466643b4a8d96d6ecdbe3237ac65f97c9d1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=31f8fb1587255c4b0dd700a9b6c8f43f8a784c2b182fd9c90e236708314b5d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e536a299bf11d6abe9d3a94183d029f1eb3e12e11b3dab41e21789869dcc93 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625418e6f83705c0ba5686b5e6c6fde73696 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb489365fc40d89e5eefae396f974201 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=91e44c0d5d9cd28abf7c8b30bb2e3d0550239b9e17953d9f089ec3d930df27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2e741b2768bfd0bbfeda04cbd22add5afa67b677a3b01af28dbaf63159b9bc + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544bf11255412b8f2aa4998140f01f99d1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe35b699e1018d03d289945c4b2e7f42 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d95cc1c999c97bbeedd5c7ec4652084d4b62a16f82500d755aa618eb4a53e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=868d5fcee2fc24e0449b05781857718f8a52fa5c7e3e91e31835579480126c + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b5821e0e9c8793543c024b5cd1f2db2d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ee55655094444f57d6b2e120a31c73e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe234b7f281411b7c6b3d7b75466259f4e5f05c12ba78c04f44432f0fba361 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9e35422ab4388dd10073b1a0ef26ad00041372fdf968809e67f56f1b6ef723 + +handshake=Noise_KK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b607e12f23e87019e6eb13b92b5c3d17ba0183cb1389dcef1a6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f550ee88c31bb77034f98d4889d5f34812eb534a2eca91ba158 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=31f8fb1587255c4b0dd700a9b6c8f43f8a784c2b182fd9c90e236708314b5d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e536a299bf11d6abe9d3a94183d029f1eb3e12e11b3dab41e21789869dcc93 + +handshake=Noise_KKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aa72dba4eb5155d2465a99e91f15ca6c1ffa47e49328ada51b0e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846662d579964a47442efacb52b05a270d3e7875aa8266a03076750c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=91e44c0d5d9cd28abf7c8b30bb2e3d0550239b9e17953d9f089ec3d930df27 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2e741b2768bfd0bbfeda04cbd22add5afa67b677a3b01af28dbaf63159b9bc + +handshake=Noise_KKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549e185b6bf0ab965775140f26a11fb5f259000251c39c78189511 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466678170eb78b10bba2423c39edf7b3642c622754f7e6de1afc949 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d95cc1c999c97bbeedd5c7ec4652084d4b62a16f82500d755aa618eb4a53e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=868d5fcee2fc24e0449b05781857718f8a52fa5c7e3e91e31835579480126c + +handshake=Noise_KKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254669c71c550b8a43b34354d21b89675f5c3ab513ce0b34156462e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466728e2a0d6eeceaee629a7e4b94070395666bc89812f54a5e443b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe234b7f281411b7c6b3d7b75466259f4e5f05c12ba78c04f44432f0fba361 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9e35422ab4388dd10073b1a0ef26ad00041372fdf968809e67f56f1b6ef723 + +handshake=Noise_NX_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663cab12734ea8f3f71a191dc053eb280e1760e951ba66c23b2d5d090d325f2bd154f933398586078af56948c397a8e522e525a530c01555483befa16d03b0a992 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8436ee9176feeba72f40eaf8763e62578ad131ddaf3d0e4706f669b0746370 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cc209ffad0968216785972cf62f4288fee898e542b62dba05cf740beac6912 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625407406c210acab2efa5a752bfc7f60f6a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e6de020041b1ed9cc0abc1ec10ffd7aab8841f05b32505bd9a4a111e3384642a8ae942b131e5cd1ffcf44770a663898c20a38eefe33480f356b9e87337056524 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a6eb79d6d2329043f6df6945f6b8dc1fad535c008f4393fb464323f179da8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=58ba0042ea02ac6e21a075a4249ac396af30b38fd6db7209070b5594313a5d + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e3b84ba49e616863bae44f4ccf12dea5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660fe07338f262359efd7e66ec1129694e277c126937f27237c19af6dfb8fe373329bfbb3fbcca0bee5b4c9b396fc871dcecb0833e162796fde3b1a82e245eff47 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e614e802e27f6218560f56fc3ac90afefc38855e54605b1ab8477408c4289c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7799c71060564989f88dcde89adbc68df6298afc5816cf5ccb1a3810ddd471 + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d98d5b739c87988f54e7981441d55055 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466945048334654701f49de37c70d567af745ec79534fc7a5b274085e6c60e07f98190ba719c270cec77adeb7bf9def9aec80a7e9b7aab8bb527908ce5ed0cb1549 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=18369c84a08bfe295c0b04773443e42ed07f8361d2fdc2d0c59dcd21284f76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e02c82141ccd4004caf2e15e112a0660475627f19400491c41468abdf04fb2 + +handshake=Noise_NX_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663cab12734ea8f3f71a191dc053eb280e1760e951ba66c23b2d5d090d325f2bd11c587cf45dd929e588e534b20082a5d02cf02b2b4188e655d60b9cb741196cbcef63ecdd5afa9805fee5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8436ee9176feeba72f40eaf8763e62578ad131ddaf3d0e4706f669b0746370 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cc209ffad0968216785972cf62f4288fee898e542b62dba05cf740beac6912 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa0a83212633a12d6bccc46857f520db476dcaf663e969d2c865 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e6de020041b1ed9cc0abc1ec10ffd7aab8841f05b32505bd9a4a111e3384642ad3b251d1a6eba26ecafaea916748c17a9c70de5e1fa6e0dd0b9954871761e1d485353b35615d6062a17a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a6eb79d6d2329043f6df6945f6b8dc1fad535c008f4393fb464323f179da8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=58ba0042ea02ac6e21a075a4249ac396af30b38fd6db7209070b5594313a5d + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6807e4adc8d6dbb87a05381de4d11f6c8f24c89895fffea5d44 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660fe07338f262359efd7e66ec1129694e277c126937f27237c19af6dfb8fe3733bfde55feb1e178d339b71b6843e8ad41ac5976d65bcc430454e87115cb8ed1f8af531005196898fbdd0a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e614e802e27f6218560f56fc3ac90afefc38855e54605b1ab8477408c4289c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7799c71060564989f88dcde89adbc68df6298afc5816cf5ccb1a3810ddd471 + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625458a2a3b6fdb1de5fbee4c4d1b909cc23178033a2176354938109 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466945048334654701f49de37c70d567af745ec79534fc7a5b274085e6c60e07f98137e010d13a87401d82cf9fa31debe616dfea637d445322350acc39cce7c5750354fae351fa25d85aedf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=18369c84a08bfe295c0b04773443e42ed07f8361d2fdc2d0c59dcd21284f76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e02c82141ccd4004caf2e15e112a0660475627f19400491c41468abdf04fb2 + +handshake=Noise_NX_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663cab12734ea8f3f71a191dc053eb280e1760e951ba66c23b2d5d090d325f2bd180a5ed192be8c4a710ac09ab86735c9d3242bc60c5111ea1e046d3d44a56357b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8436ee9176feeba72f40eaf8763e62578ad131ddaf3d0e4706f669b0746370 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cc209ffad0968216785972cf62f4288fee898e542b62dba05cf740beac6912 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546f0bbfa57497b723e7b2df35f66e5b49 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e6de020041b1ed9cc0abc1ec10ffd7aab8841f05b32505bd9a4a111e3384642a5689f8f05401600a5b6d74e118644166f25301de37703a013fdad04de6aaddf8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a6eb79d6d2329043f6df6945f6b8dc1fad535c008f4393fb464323f179da8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=58ba0042ea02ac6e21a075a4249ac396af30b38fd6db7209070b5594313a5d + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547e8ba6bebe1a900604e09647da4bea6b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660fe07338f262359efd7e66ec1129694e277c126937f27237c19af6dfb8fe37332b83b975639a4c5476e4b308afe63b3d7e0502681de388787adaccb7912c594c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e614e802e27f6218560f56fc3ac90afefc38855e54605b1ab8477408c4289c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7799c71060564989f88dcde89adbc68df6298afc5816cf5ccb1a3810ddd471 + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254abd5c4dbcd9bec08f5785ceef88c8c2f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466945048334654701f49de37c70d567af745ec79534fc7a5b274085e6c60e07f987241469b3c8de0e1b02a94b215ead3207a8c188be0a5c7677e33d1d765308d42 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=18369c84a08bfe295c0b04773443e42ed07f8361d2fdc2d0c59dcd21284f76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e02c82141ccd4004caf2e15e112a0660475627f19400491c41468abdf04fb2 + +handshake=Noise_NX_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663cab12734ea8f3f71a191dc053eb280e1760e951ba66c23b2d5d090d325f2bd1819782ed84cf6815a49c0186e95910d22cf02b2b4188e655d60b3f1f5941cce7dec8fa01ce3c55c671c2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8436ee9176feeba72f40eaf8763e62578ad131ddaf3d0e4706f669b0746370 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cc209ffad0968216785972cf62f4288fee898e542b62dba05cf740beac6912 + +handshake=Noise_NXpsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa0a83212633a12d6bcc9a6171915f8250f6e22ee5eb9935005c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e6de020041b1ed9cc0abc1ec10ffd7aab8841f05b32505bd9a4a111e3384642a7b72e559f79e16ba912e9e42d693318d9c70de5e1fa6e0dd0b99aee00aea4e091c9c78558b0dda450750 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6a6eb79d6d2329043f6df6945f6b8dc1fad535c008f4393fb464323f179da8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=58ba0042ea02ac6e21a075a4249ac396af30b38fd6db7209070b5594313a5d + +handshake=Noise_NXpsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6807e4adc8d6dbb87a0ae8cdebfa23da36d298070b955c319ab +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660fe07338f262359efd7e66ec1129694e277c126937f27237c19af6dfb8fe37332302e237cbffd3e19f431a1cc57ea233ac5976d65bcc430454e825bf561eaaac606af413730ed8b93383 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e614e802e27f6218560f56fc3ac90afefc38855e54605b1ab8477408c4289c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7799c71060564989f88dcde89adbc68df6298afc5816cf5ccb1a3810ddd471 + +handshake=Noise_NXpsk2_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625458a2a3b6fdb1de5fbee4e074465318c6eb7e520349b275865007 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466945048334654701f49de37c70d567af745ec79534fc7a5b274085e6c60e07f98412430a46f760ec9e1a6849c01302cda6dfea637d445322350acca1bb1953e282c6dca68169edb531404 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=18369c84a08bfe295c0b04773443e42ed07f8361d2fdc2d0c59dcd21284f76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e02c82141ccd4004caf2e15e112a0660475627f19400491c41468abdf04fb2 + +handshake=Noise_KX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d750365e947a92608f1c492f6d7a07b738ad37cd00e241497371929a94c4e6d02ec1185f23719493931cc5fa4ab2f7fb197acfe601403b4cdc967bd4cfbfaa89 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=120302ad872ca2e8e3b44a5b25ee43323ebf5abc3ac15cb6cb5a5b6367f06d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e276ab45beaadc196449e0137fc9c45531a4452153b1ef0f732caa7e9fe65 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625468f71c2faf195aa778d37d4cc2859372 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d2a0c08410deab404ac28d06fd35af5d5a1f7b45db9be3842df0988cf20cc7f433847dca55766a1df984e2d6387336ee54acbd608d81d44911b68d22f18ca5af +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c406f3b52c73e6224bd731a3ff48b84c28ce5208cab54fd266e27003a925a3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05e22b85e52a23eabb16edc9afae206d59c234922e75f8385e65db5a56bfe8 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549dd6608dbfbdd3cf57c0f8169912c0ae +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466106146b159cbf91766e59566ea4c89cadf4b72f33418c93919793fdf6c00642117d43f701bda94e37d0cac2bc4490ff97557188ed6165537241084fa6609d7dd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8a3ddb48d59389bdac13a351f63d1f47e3aae4e56f849ca12f48195e751e15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=625c80ee8afe830d7944fc7c33bf51077d94cc75433369d849f42d63edb751 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419f548b86c9a3238c72eb37b232d8679 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a08a362949425a6abadf4e80b05db9449b0dbdbfbec6eb5220f535d9356f58a304f0c8066c9d955713b561b2925ee07af6f62f0a218a78ca75d68e0c84fb3350 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42f348cf45b8ad1afbc3001151fde2c70109ea3c5cfb69d3de99fb5ffae827 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f68b6f3d97446f0e6510305eca839209f57506f3a02cbf38280352ea0e1a1 + +handshake=Noise_KX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d750365e947a92608f1c492f6d7a07b738ad37cd00e241497371929a94c4e6d0c4391a81757745480b7942495aa1f6650aa5c2a82a32eef9e381e107cbdb021584921e8a54aca1ba1cd7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=120302ad872ca2e8e3b44a5b25ee43323ebf5abc3ac15cb6cb5a5b6367f06d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e276ab45beaadc196449e0137fc9c45531a4452153b1ef0f732caa7e9fe65 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625413c4eabc370d35e3b373f9fab0cc0bbee8b4f32d3409f7cb4ead +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d2a0c08410deab404ac28d06fd35af5d5a1f7b45db9be3842df0988cf20cc7f4290baa0275f98fb151d5b19cdab8b58a59abc604fa23da55cb1bd4704b68e91f690a23973a314a9f5dca +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c406f3b52c73e6224bd731a3ff48b84c28ce5208cab54fd266e27003a925a3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05e22b85e52a23eabb16edc9afae206d59c234922e75f8385e65db5a56bfe8 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b0f32759f1f61814826cbb693d34eb145f02a963fa85a6ab4009 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466106146b159cbf91766e59566ea4c89cadf4b72f33418c93919793fdf6c0064213f1f0f4c663b52091ac62d3acf442a74f5b738a71ccc543faf343b8dc949b31c79e37545eb8764d036de +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8a3ddb48d59389bdac13a351f63d1f47e3aae4e56f849ca12f48195e751e15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=625c80ee8afe830d7944fc7c33bf51077d94cc75433369d849f42d63edb751 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547b501815e69557bb5cf7c66a8311d8e798bab5eb7f85ec9fa07c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a08a362949425a6abadf4e80b05db9449b0dbdbfbec6eb5220f535d9356f58a3588e06ea64363458b186ea7df3d01e7b69d1855ec9bd0fbf751bc2ef6243ff5bffd1225474d6bfef9e36 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42f348cf45b8ad1afbc3001151fde2c70109ea3c5cfb69d3de99fb5ffae827 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f68b6f3d97446f0e6510305eca839209f57506f3a02cbf38280352ea0e1a1 + +handshake=Noise_KX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d750365e947a92608f1c492f6d7a07b738ad37cd00e241497371929a94c4e6d0bc0e94d7a1cacca75268186bde15c7b68d93f6743aa9942f32dc4996837c5a4f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=120302ad872ca2e8e3b44a5b25ee43323ebf5abc3ac15cb6cb5a5b6367f06d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e276ab45beaadc196449e0137fc9c45531a4452153b1ef0f732caa7e9fe65 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a5b967e598dfffe9edb3f022904f70e0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d2a0c08410deab404ac28d06fd35af5d5a1f7b45db9be3842df0988cf20cc7f461dfc24838b85365bfdf871c46adb9b14154a3cf4d24f5da0de13d84b0661caf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c406f3b52c73e6224bd731a3ff48b84c28ce5208cab54fd266e27003a925a3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05e22b85e52a23eabb16edc9afae206d59c234922e75f8385e65db5a56bfe8 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544e148e82b52660be5c80f764a5d85cae +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466106146b159cbf91766e59566ea4c89cadf4b72f33418c93919793fdf6c006421036d52401f286d5f4f2dbcf1abcca8b1e076366728cc163d434715979894289f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8a3ddb48d59389bdac13a351f63d1f47e3aae4e56f849ca12f48195e751e15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=625c80ee8afe830d7944fc7c33bf51077d94cc75433369d849f42d63edb751 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625435474615c969451fe17e73448a5e9cdf +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a08a362949425a6abadf4e80b05db9449b0dbdbfbec6eb5220f535d9356f58a37944ba3ebea3c35d041afeb9fd2eb648073e2e9fb6f39243f7c010c41a3b0dd3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42f348cf45b8ad1afbc3001151fde2c70109ea3c5cfb69d3de99fb5ffae827 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f68b6f3d97446f0e6510305eca839209f57506f3a02cbf38280352ea0e1a1 + +handshake=Noise_KX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d750365e947a92608f1c492f6d7a07b738ad37cd00e241497371929a94c4e6d0f60083401ee9c6620039c34566f38f0b0aa5c2a82a32eef9e381ae8acf215c4525e92c68a6c3f7bbd537 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=120302ad872ca2e8e3b44a5b25ee43323ebf5abc3ac15cb6cb5a5b6367f06d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e276ab45beaadc196449e0137fc9c45531a4452153b1ef0f732caa7e9fe65 + +handshake=Noise_KXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625413c4eabc370d35e3b37348719e87dc9f4a12d1ac3b597b94a40d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d2a0c08410deab404ac28d06fd35af5d5a1f7b45db9be3842df0988cf20cc7f47e0091dd10704dd2b2f1e8b9eb51168459abc604fa23da55cb1b05a5dd2f586a0557c0e207704830f000 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c406f3b52c73e6224bd731a3ff48b84c28ce5208cab54fd266e27003a925a3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=05e22b85e52a23eabb16edc9afae206d59c234922e75f8385e65db5a56bfe8 + +handshake=Noise_KXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b0f32759f1f61814826c4976c6e28b0a7ea7abac5d434a636617 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466106146b159cbf91766e59566ea4c89cadf4b72f33418c93919793fdf6c006421188de02a0d30be64807108e8e1f6bbacf5b738a71ccc543faf34078d7e42f606594a2058747095b8657f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8a3ddb48d59389bdac13a351f63d1f47e3aae4e56f849ca12f48195e751e15 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=625c80ee8afe830d7944fc7c33bf51077d94cc75433369d849f42d63edb751 + +handshake=Noise_KXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547b501815e69557bb5cf7dcdf6a40f62bd8c34a0dd2f667bb010a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a08a362949425a6abadf4e80b05db9449b0dbdbfbec6eb5220f535d9356f58a378ff6d119df2343b7960b727fe2ffaaf69d1855ec9bd0fbf751b71ac4833b739b3e246b9b5441cad9fd2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42f348cf45b8ad1afbc3001151fde2c70109ea3c5cfb69d3de99fb5ffae827 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f68b6f3d97446f0e6510305eca839209f57506f3a02cbf38280352ea0e1a1 + +handshake=Noise_XN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466988474c4bc814eac3a4eb6e448d4acd0 +msg_2_payload= +msg_2_ciphertext=b1a131ae945d7cccbc46e74eed3289875967c9b743dff16c2cc404ee27cbeb70af25ce82007ae6deba2a37e1085023fe89248b5245916d6450c4e4582068dcba +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5812ae8d9c624ecb85f39515859c1cccff15caf017bb91db106b46c6924ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20231a53dcc59ca97eeaa2a43394e5b4fc073716896e9a3ccac9387ea01243 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541878c2328b45e172f0dfbad0e3b3aa68 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663471c9d8776d5e49564cab43e9e79186 +msg_2_payload= +msg_2_ciphertext=a87b061dff06c9a56457e1d6a4c7c4df6b8769f343c1f1b33551f6bcc263c848e3be3328718b68bed193c51fb11ff996efc661808169b463ce1248ae676f50cd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5956d8aae09289cdb03185f9b63de52f1447a79e307c6e604ccf817253a5f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cda6e68ed4b4402b9ae56caf4d16db4f994a5ddcf65aa9f3a915307089859 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254139465c03bc36f484cfc79b470d666cd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466704ab2dc4aeb2a61d5782c0778070e8b +msg_2_payload= +msg_2_ciphertext=c816ad72c489e34b006988edc566f969ed71de0eb8f1254e5ec39eae02f27426058b160cd6bf1f495b6b0256fc2466f5471a45880c790198bdd1dbb448d53e4c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=913446cef1a493a0fd96acdd702f5d772a9842c8545a96a4ef91b068eaafeb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5cc60635e934808c5a577baf0287316c34364c95667ad380a0b8fc4c9a3ad4 + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254088fae778f2f23315be81b8c5bbf4199 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846691de153aa38c996296165b23e39e4ba5 +msg_2_payload= +msg_2_ciphertext=c44848a758d20c51f1207057a6b75b5c30742221577758d0dd6f4d2ec7265b6991ca389832770d6646645f078ebfacfb4ef98fb67b22ef093c90b2b2de7261f5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=454db968e85c0aa2018661c23973686005f5add451ae7bef0eba43ca978ebb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=660a63b91e195715c181bfc04c12d6141dd1f0a6f3b77be74dbbf4a0aae7e6 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625451e1b61a8dbb4cb8e33299a9f717cc7b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664ee2b9a6fb5aa8606f177824e9fed5bc +msg_2_payload= +msg_2_ciphertext=9f5dd4a9797066f984199e97e45af174bf8cd61adfdcd0fe178e495304bf52954113aaa5963a11be301b4034533fe0d142d11f4408aa61eb1be560849c3fdf1f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c40a299a4178ef3fc65641b39fab602d4d0112e4df25ef5ee667101280053f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=0d80b82f62dba76f15ae04b55da791d5e7e1ec6c2c0a66762188e3c7f69815 + +handshake=Noise_XN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668ebd9d2110458ed54d5d12597a6218330b3fcbdfb59963b6c0cd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b1a131ae945d7cccbc46e74eed3289875967c9b743dff16c2cc404ee27cbeb707987c7eb9fb15e7b3425014e33ee2bdedede11aff10daa4794db8599579ba04348824534044c310360ee +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5812ae8d9c624ecb85f39515859c1cccff15caf017bb91db106b46c6924ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20231a53dcc59ca97eeaa2a43394e5b4fc073716896e9a3ccac9387ea01243 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625453bcb5ed740103515a70dccc5027f82ea16645c2cf12a4d0418e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe5ae95f4d654f81ba88e2da3c9073cf753f83fcaa3392795c2b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a87b061dff06c9a56457e1d6a4c7c4df6b8769f343c1f1b33551f6bcc263c848ccd48e7a836de5a78f57ca660f9b0c0ae4019430d508e72e8b027a3dba64aa2421c14568bc5612ca39fe +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5956d8aae09289cdb03185f9b63de52f1447a79e307c6e604ccf817253a5f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cda6e68ed4b4402b9ae56caf4d16db4f994a5ddcf65aa9f3a915307089859 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254abe5c0277ce6547f2ef97887cb94162fc9ab8cf6ea2cb46f493b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667ba91997827a5f176569ff971962880e2b25094007ac03a8d95e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c816ad72c489e34b006988edc566f969ed71de0eb8f1254e5ec39eae02f274269138a3ae41d01e9d650a02787f12d35d15ec0e8394c3c28c4a208d01b35e9f6a29f2b30436827358e296 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=913446cef1a493a0fd96acdd702f5d772a9842c8545a96a4ef91b068eaafeb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5cc60635e934808c5a577baf0287316c34364c95667ad380a0b8fc4c9a3ad4 + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625430c66d8c51d826469cb0ed6da6f0e4a3b46262b84ecf63e0174f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846684ab0ec2868afa8fd41a339d9585c2be4aef7c24748d994e3ff8 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c44848a758d20c51f1207057a6b75b5c30742221577758d0dd6f4d2ec7265b6901bdc2e6295cb723ece5a0204021b93950d7406e563d02635e25b6656e46e0d84ac375737476397453f2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=454db968e85c0aa2018661c23973686005f5add451ae7bef0eba43ca978ebb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=660a63b91e195715c181bfc04c12d6141dd1f0a6f3b77be74dbbf4a0aae7e6 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c47ebd8ffeb5672cb656bbfc0dec33c35496395a6db41a88417d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672c56c783089c040fd9a9a3a568f1b9e6a28bf847f3e0bc30c3d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=9f5dd4a9797066f984199e97e45af174bf8cd61adfdcd0fe178e495304bf5295104af70ebac3b9df92578c538c2392360020415ec8cf0ee4c2dbbe42223069e1c1deb42a2959eea770f8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c40a299a4178ef3fc65641b39fab602d4d0112e4df25ef5ee667101280053f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=0d80b82f62dba76f15ae04b55da791d5e7e1ec6c2c0a66762188e3c7f69815 + +handshake=Noise_XN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846673271030e0003fb2df82539007eca645 +msg_2_payload= +msg_2_ciphertext=b1a131ae945d7cccbc46e74eed3289875967c9b743dff16c2cc404ee27cbeb70e4c109520e2d30a41c95652cd08b77d4df4a342bd396735eab5e28b47620ab8a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5812ae8d9c624ecb85f39515859c1cccff15caf017bb91db106b46c6924ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20231a53dcc59ca97eeaa2a43394e5b4fc073716896e9a3ccac9387ea01243 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625436c9321ebf714c9519214b097526e929 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664745d67a61913ce52d624f8df114c9b0 +msg_2_payload= +msg_2_ciphertext=a87b061dff06c9a56457e1d6a4c7c4df6b8769f343c1f1b33551f6bcc263c8483b4480058a82d425f3e43396950abbc58cd5097f9b26a79b0074d50200d2aa9b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5956d8aae09289cdb03185f9b63de52f1447a79e307c6e604ccf817253a5f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cda6e68ed4b4402b9ae56caf4d16db4f994a5ddcf65aa9f3a915307089859 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544ad2c659c6e1ca08e814589f0b4ab8da +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d34fd899cd1663695b2898236c3e0b5f +msg_2_payload= +msg_2_ciphertext=c816ad72c489e34b006988edc566f969ed71de0eb8f1254e5ec39eae02f27426a7a4a69a02c7173a0ed58f36ef99bb7ed04b7ea534f8cfdc3df971fc5d83d612 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=913446cef1a493a0fd96acdd702f5d772a9842c8545a96a4ef91b068eaafeb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5cc60635e934808c5a577baf0287316c34364c95667ad380a0b8fc4c9a3ad4 + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b0d6eb79c92622a3a96d2cbde54d5ee1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846613d3b417279df8b6bf62ea4c898c1ccf +msg_2_payload= +msg_2_ciphertext=c44848a758d20c51f1207057a6b75b5c30742221577758d0dd6f4d2ec7265b692d513bf753446df5d0cdcb2ca7b812e2f2fe48a691a82468faac983edca29a53 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=454db968e85c0aa2018661c23973686005f5add451ae7bef0eba43ca978ebb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=660a63b91e195715c181bfc04c12d6141dd1f0a6f3b77be74dbbf4a0aae7e6 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c00554c4225bf63afcbbf37eaf0bb7c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846686ba345caf5f9a6c1af1d61c0ebebabb +msg_2_payload= +msg_2_ciphertext=9f5dd4a9797066f984199e97e45af174bf8cd61adfdcd0fe178e495304bf52954b0996fc15cbe197806147e53701f6b3449a291a4fa39281652e1089230529c1 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c40a299a4178ef3fc65641b39fab602d4d0112e4df25ef5ee667101280053f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=0d80b82f62dba76f15ae04b55da791d5e7e1ec6c2c0a66762188e3c7f69815 + +handshake=Noise_XN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668ebd9d2110458ed54d5ddccba5d5ecd3cbc9839829239a072d47 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b1a131ae945d7cccbc46e74eed3289875967c9b743dff16c2cc404ee27cbeb70087cae99cdb9325ed5d8e298eaa530a2dede11aff10daa4794db4e83b79ef22753e3dbe12caeb949dc6d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b5812ae8d9c624ecb85f39515859c1cccff15caf017bb91db106b46c6924ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=20231a53dcc59ca97eeaa2a43394e5b4fc073716896e9a3ccac9387ea01243 + +handshake=Noise_XNpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625453bcb5ed740103515a707998faf9a6f44cdee5b6d00344ad53e7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe5ae95f4d654f81ba8861439ac7a95d1f953ba67f3842a18432 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a87b061dff06c9a56457e1d6a4c7c4df6b8769f343c1f1b33551f6bcc263c8482aa326dc128555199a32b5d152079b5be4019430d508e72e8b028ee24bf4b647ecb32c58f90e9bbeed5c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a5956d8aae09289cdb03185f9b63de52f1447a79e307c6e604ccf817253a5f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cda6e68ed4b4402b9ae56caf4d16db4f994a5ddcf65aa9f3a915307089859 + +handshake=Noise_XNpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254abe5c0277ce6547f2ef907329e13b94de50d15352ae9d78508e3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667ba91997827a5f176569ed5acaf721d9134fae48f89e345f6656 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c816ad72c489e34b006988edc566f969ed71de0eb8f1254e5ec39eae02f27426df4e9fc31bfc969eb43577d1a4b8fe5b15ec0e8394c3c28c4a201364d8f1cc36146d4e71612d0ac7bb7a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=913446cef1a493a0fd96acdd702f5d772a9842c8545a96a4ef91b068eaafeb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5cc60635e934808c5a577baf0287316c34364c95667ad380a0b8fc4c9a3ad4 + +handshake=Noise_XNpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625430c66d8c51d826469cb091809304068a4c45b31d201e3d6984d9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846684ab0ec2868afa8fd41a8364284dcac1f6504dcbfb64f7fc2c89 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c44848a758d20c51f1207057a6b75b5c30742221577758d0dd6f4d2ec7265b6955b7fbb5a9569540fb2894de52721ca250d7406e563d02635e2538f99a17e3c60de4afdc7f6845d12ffb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=454db968e85c0aa2018661c23973686005f5add451ae7bef0eba43ca978ebb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=660a63b91e195715c181bfc04c12d6141dd1f0a6f3b77be74dbbf4a0aae7e6 + +handshake=Noise_XNpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c47ebd8ffeb5672cb6563d3b2e8a24f22064c2824778c9ee1e1d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846672c56c783089c040fd9aaf2198289d220313c7d715b060de7d11 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=9f5dd4a9797066f984199e97e45af174bf8cd61adfdcd0fe178e495304bf5295949f59aa6dcd20a9c8878b89303af7390020415ec8cf0ee4c2dbf425b90a723b4e45f296f6dd79243adf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c40a299a4178ef3fc65641b39fab602d4d0112e4df25ef5ee667101280053f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=0d80b82f62dba76f15ae04b55da791d5e7e1ec6c2c0a66762188e3c7f69815 + +handshake=Noise_IN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dc3a487d9accc35b9ae9b1c394217018 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a19d6a777dfbe1012232727ad0c04cb68d76b903dcc87dd505b85bab3e5433 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ce308865d60653f9e63cab1f039b63261ed5c37d1369020db0b2d8965a4b5a + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa66a1d13c5e040a571cb62797f389f0bdc93b9d6a3d2916377e9def67461897b1fc44f1e9763665e80e00027d1f18182163f1ddd3634dd27996f029a73bad65 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a15c2ffd0b6dde640803eab560d0a319 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=412466f3e30dbe8a0fcf5c7623ca89cf12aa18f0032261d8dbdb01ddfd9722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c261cf8d2744677ee33080e07dec1fae865dcd42ce44f0bd11deb0103d46f + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d0a33a5ca38ecd21362d671912fda8b15c33d39b4fd6a201ccaffd930371ec7ca83d762b357eb53be91392561c46d05fe177f9abe3298172695f49d07143787 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846626f2dd6ee861f026bd4f332a4a7cf281 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0ca0780e8b14b25ac4c10c848700fcfe6eb3375a79646f0246140ce0a38f7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ba8833e1c68886ac6610c85f6577fa357a6342e9af3a631c0af908e8f1b4a6 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549261456b2aeb37966de232efa6cfc0d4d53fdcd7b9dc13c6f5969bf113c23f3b4a99c06df30d020a9918405444e90c798f56c43c2f6ee53a95f35c013df24cf1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669e0f90ae816bc5861579e1fc3dac31cf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5035ddbf91e81c481603d0a90e76a9afda117318298b758ff0be2645129d8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6cfd82e4b22fdd8a45c4c3778c385cda5e05538d7bf300b9dc6d11be818d71 + +handshake=Noise_IN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846680415c34cf9cd2fcc5ff07ff0515d320986d75947d3e92887e33 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a19d6a777dfbe1012232727ad0c04cb68d76b903dcc87dd505b85bab3e5433 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ce308865d60653f9e63cab1f039b63261ed5c37d1369020db0b2d8965a4b5a + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa66a1d13c5e040a571cb62797f389f0bdc93b9d6a3d2916377e9def67461897b1fc44f1e9763665e80e00027d1f18184d5e8c562d7176a44745bc732b92f1f6a47b8fee4fc04ebb0d7b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e210d10ffdd00b89c314bd8e118bbcf655d41d25db568d805ada +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=412466f3e30dbe8a0fcf5c7623ca89cf12aa18f0032261d8dbdb01ddfd9722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c261cf8d2744677ee33080e07dec1fae865dcd42ce44f0bd11deb0103d46f + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d0a33a5ca38ecd21362d671912fda8b15c33d39b4fd6a201ccaffd930371ec7ca83d762b357eb53be91392561c46d05f58ed688af22ea17c28eae9ad84b58de5d775f4cb08d73316c88 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c6649a9c5a7cc255713f1e47aa65ea192f550a54ba3d420afe5f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0ca0780e8b14b25ac4c10c848700fcfe6eb3375a79646f0246140ce0a38f7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ba8833e1c68886ac6610c85f6577fa357a6342e9af3a631c0af908e8f1b4a6 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549261456b2aeb37966de232efa6cfc0d4d53fdcd7b9dc13c6f5969bf113c23f3b4a99c06df30d020a9918405444e90c797485540b3e84439995285bfd581df450b29769fc6b2de211a440 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669238932916977e5aa74ab7b5f3db22ac8b916a65a3c33075008f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5035ddbf91e81c481603d0a90e76a9afda117318298b758ff0be2645129d8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6cfd82e4b22fdd8a45c4c3778c385cda5e05538d7bf300b9dc6d11be818d71 + +handshake=Noise_IN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e1250b022b6dd38ae0ef98de771c551f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a19d6a777dfbe1012232727ad0c04cb68d76b903dcc87dd505b85bab3e5433 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ce308865d60653f9e63cab1f039b63261ed5c37d1369020db0b2d8965a4b5a + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa66a1d13c5e040a571cb62797f389f0bdc93b9d6a3d2916377e9def674618979df913c2e470e1e1533482ddd46d9009f84515ec8c05d6089bef6b0db4701428 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466de2ebdfc7517338ef3e808c6a357f034 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=412466f3e30dbe8a0fcf5c7623ca89cf12aa18f0032261d8dbdb01ddfd9722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c261cf8d2744677ee33080e07dec1fae865dcd42ce44f0bd11deb0103d46f + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d0a33a5ca38ecd21362d671912fda8b15c33d39b4fd6a201ccaffd930371ec7a7632ec505c484737048c2713e259053d774d5a366f33a64a9369065c6e07b67 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ef84513938c77cb34209e0d1d2bc52bc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0ca0780e8b14b25ac4c10c848700fcfe6eb3375a79646f0246140ce0a38f7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ba8833e1c68886ac6610c85f6577fa357a6342e9af3a631c0af908e8f1b4a6 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549261456b2aeb37966de232efa6cfc0d4d53fdcd7b9dc13c6f5969bf113c23f3b414349604be5302d44a87c1de3df2357e5ee5528292efb2e05ae15c414969849 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667915d63c972f647573c2255d86bd0916 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5035ddbf91e81c481603d0a90e76a9afda117318298b758ff0be2645129d8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6cfd82e4b22fdd8a45c4c3778c385cda5e05538d7bf300b9dc6d11be818d71 + +handshake=Noise_IN_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846680415c34cf9cd2fcc5ff02c8f4f0e18740f9a54b24ff9f09a690 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a19d6a777dfbe1012232727ad0c04cb68d76b903dcc87dd505b85bab3e5433 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ce308865d60653f9e63cab1f039b63261ed5c37d1369020db0b2d8965a4b5a + +handshake=Noise_INpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa66a1d13c5e040a571cb62797f389f0bdc93b9d6a3d2916377e9def674618979df913c2e470e1e1533482ddd46d90094d5e8c562d7176a447450da75537282462cc96b900debc7e749d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e210d10ffdd00b89c3148aa8c3a69d47184af76d60acfec093c2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=412466f3e30dbe8a0fcf5c7623ca89cf12aa18f0032261d8dbdb01ddfd9722 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0c261cf8d2744677ee33080e07dec1fae865dcd42ce44f0bd11deb0103d46f + +handshake=Noise_INpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d0a33a5ca38ecd21362d671912fda8b15c33d39b4fd6a201ccaffd930371ec7a7632ec505c484737048c2713e259053f58ed688af22ea17c28e8271a57ef385d1c0c409eb563b360eeb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c6649a9c5a7cc255713fa8b7c1d04992e2c3b3af30d5daa82c25 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0ca0780e8b14b25ac4c10c848700fcfe6eb3375a79646f0246140ce0a38f7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ba8833e1c68886ac6610c85f6577fa357a6342e9af3a631c0af908e8f1b4a6 + +handshake=Noise_INpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549261456b2aeb37966de232efa6cfc0d4d53fdcd7b9dc13c6f5969bf113c23f3b414349604be5302d44a87c1de3df23577485540b3e844399952860995d9d1c90781fe677edc6d35867e7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669238932916977e5aa74aafe1d638562cec623b848e26b4df7a71 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=5035ddbf91e81c481603d0a90e76a9afda117318298b758ff0be2645129d8e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6cfd82e4b22fdd8a45c4c3778c385cda5e05538d7bf300b9dc6d11be818d71 + +handshake=Noise_XK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625490210797b3a07855f135b5bdbbddf165 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664733671042d65e0eb2ff0a9e7a9c7c9f +msg_2_payload= +msg_2_ciphertext=4324e614b0f53d138eaa88364af70c285c29f6f0a39a9205a67e60c4abe97668fd8020f0feee69a839100d5f262cb9314c619d97600d2e7acef6d5d39a7489fb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7a58f180a45f63401657a7a4817ac5c34dae211e1fbafcb8c42aaccb6c4fd5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e39cc5c38f30dd358deed825a045e77c96c856d9957b5eed88c6704cd113b3 + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548e209c79c8ea8a562a17a10307c60e87 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669498034db343934e058df83380897eab +msg_2_payload= +msg_2_ciphertext=e7ee54258e880e01a57de43cacc12c5799e34ed9beb0e3d0d64dfc3d0e1dd0bfc27656f27cc417501e9769a73d8143adba8e31493d7415a5c58cbebd6c35c278 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d85c66f45b68d04f1317197985ebbd021defdcec3bc7902c940754c7fe7175 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d6b2f036e6cac49e862ccbcbfd359ea858a7c8e3cff228506758633ec53276 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547ce9d900de63dd0b5e9b840ad3f12149 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466088ad43090816c338733ba917a3a1853 +msg_2_payload= +msg_2_ciphertext=5008b6f662503afac70502840b3520d72b641a06dbc77426475b0b83eac6aa18e595fca7739b5985df46c9dea693614d5e44c50f9c9541ce7b80be0547c94050 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=60abaa1cdd2f173576adcd2f93d5d5737c4ef63598ee3ff6c006a6eb3c9266 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=61261512d684c773a79724182988e8382cd571a3d6aa4703cf1a17a0550204 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f5ae1b7c7a2c2d21366d159eba7965a5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466381bc604f56a554d4660ed44ff9b67b0 +msg_2_payload= +msg_2_ciphertext=aa2b2e3078aa0054ca436df384c021f5bef28fbe3a9fb6608fc8f0e5a9a1faff3e12483b03fa8a28bf453b2ad69e18fb28624c08b45c1117694bfa6bd86a8d15 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=25ff84a3cb83d33bdf1559428a7d55ff15bdb042db3c85321346e2894a70f9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8be89bcd7bf5bc0326872bf15216c83b19df6d3f14b2744fa60138e364646c + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625474ef4fdbe6a15dbbd752aba5a6cba0b9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466229f6b33b965af8a156dfa1a75e674d3 +msg_2_payload= +msg_2_ciphertext=75ef1297edb57f0efa872372675293bc721ecb4f58ee1d87012ff7069f4ff38b2f4c335d892fc2d7dd639a86382703c9d3ef7e99a00f439f51c51e804b0ea502 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e2c8d3c21594d58f0d7da8d4d40cb0b47ca6b0831e5f8f4ae66966aea4c8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cba677284723c05166976ceb2146d2978e38f17e102780c71cf11416272c8 + +handshake=Noise_XK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254663eea19e1c296b8b49ff4f25ea226b3a7deb26fd267bf07d26c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b29eebb8f9cd52c9835ec61f24bce5cf57eeb626ad1f9f23b3ac +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4324e614b0f53d138eaa88364af70c285c29f6f0a39a9205a67e60c4abe97668ce4e19a9e6ffb5c7faee8b79e3abe64f8bc983cb75059b3f3901d2dad6001f5d28fa78aa8749effe3566 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7a58f180a45f63401657a7a4817ac5c34dae211e1fbafcb8c42aaccb6c4fd5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e39cc5c38f30dd358deed825a045e77c96c856d9957b5eed88c6704cd113b3 + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544063ca1a8f35a6c0d7fb694032a174907330e3a3c8c6c2ffe073 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bbd683767d4eabfb2908900e264d6e56078f380975020348fe3e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e7ee54258e880e01a57de43cacc12c5799e34ed9beb0e3d0d64dfc3d0e1dd0bf3dd4e97663863b3a0ed3e3db5ecdce7e9dceae07adfa85906cfdb8fb73388c85dbd34a6b2e80067d9a18 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d85c66f45b68d04f1317197985ebbd021defdcec3bc7902c940754c7fe7175 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d6b2f036e6cac49e862ccbcbfd359ea858a7c8e3cff228506758633ec53276 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c0e58be3d117a08f563f1b81ddddf832cf92b0ef2ac7afaabead +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660e4d7c7e528beab53894c8d0ff81686928997ec6472ed87c94a2 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5008b6f662503afac70502840b3520d72b641a06dbc77426475b0b83eac6aa18447f5e5fbac32f7d1f206e82fc21319380bba5482b6c23826fbdb993b5aa8af89b038ed837de8a0c1c86 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=60abaa1cdd2f173576adcd2f93d5d5737c4ef63598ee3ff6c006a6eb3c9266 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=61261512d684c773a79724182988e8382cd571a3d6aa4703cf1a17a0550204 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c0ff9243a441a9a38229d6b3a8cf3d920e7215c68d36e0d392bd +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633ca26c2f74a980f4014d7fb2dcecb2bd4d68077063b0f28b1d3 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=aa2b2e3078aa0054ca436df384c021f5bef28fbe3a9fb6608fc8f0e5a9a1faffe4c3fdf4acfdc9d13750e31c72452fa0df12674bfe6a8e2c907ef9cf91cc273f486ee62cb02ff54a4c50 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=25ff84a3cb83d33bdf1559428a7d55ff15bdb042db3c85321346e2894a70f9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8be89bcd7bf5bc0326872bf15216c83b19df6d3f14b2744fa60138e364646c + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545137f1f9a9ec7de03e77d735c92d8b4621ce96029727f4178386 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846610ae8c7cae2e22da73ff83374fcf9057e91f2f0cff1887955750 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=75ef1297edb57f0efa872372675293bc721ecb4f58ee1d87012ff7069f4ff38b4cf30e167d4b617817cda8df5a9762d97a7771f21e0af8ae4f3a7b85e1cf9d28d325c6eba8b7380c0c89 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e2c8d3c21594d58f0d7da8d4d40cb0b47ca6b0831e5f8f4ae66966aea4c8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cba677284723c05166976ceb2146d2978e38f17e102780c71cf11416272c8 + +handshake=Noise_XK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254541b04eabcea3087b9ca2dde2bb9278b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dba3bcbb6e7023a137e00ac858b48e1c +msg_2_payload= +msg_2_ciphertext=4324e614b0f53d138eaa88364af70c285c29f6f0a39a9205a67e60c4abe9766882cd224050fe4084445cdc1250c47ca5bd039aa3a101885f18e12a2504722fb2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7a58f180a45f63401657a7a4817ac5c34dae211e1fbafcb8c42aaccb6c4fd5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e39cc5c38f30dd358deed825a045e77c96c856d9957b5eed88c6704cd113b3 + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549fe2024079bf5448d04ff45c33883985 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666048bf15fae44ad97f00d62dc0ca8c3 +msg_2_payload= +msg_2_ciphertext=e7ee54258e880e01a57de43cacc12c5799e34ed9beb0e3d0d64dfc3d0e1dd0bf75984919ae5741b23644ff3d5379b7d2f08ebe5fb8a95356cfe7ac933b9e153e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d85c66f45b68d04f1317197985ebbd021defdcec3bc7902c940754c7fe7175 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d6b2f036e6cac49e862ccbcbfd359ea858a7c8e3cff228506758633ec53276 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254073ecb95033a08aac58e5d4222c1d762 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846600b9141e162440a021c65a0e1787cddd +msg_2_payload= +msg_2_ciphertext=5008b6f662503afac70502840b3520d72b641a06dbc77426475b0b83eac6aa18e6282572b9342ee071855fcad25c59582b9cad4e1fa63e8b977961b724790442 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=60abaa1cdd2f173576adcd2f93d5d5737c4ef63598ee3ff6c006a6eb3c9266 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=61261512d684c773a79724182988e8382cd571a3d6aa4703cf1a17a0550204 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625473f4564e2d12165fbde2a66c10c71dfc +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669a8598e26a4635a2164c15ff96b58cd2 +msg_2_payload= +msg_2_ciphertext=aa2b2e3078aa0054ca436df384c021f5bef28fbe3a9fb6608fc8f0e5a9a1faffdadbbe77cdc53902d9c627a96d91e19e99c72e2e38997d762ac9d6a303edde2b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=25ff84a3cb83d33bdf1559428a7d55ff15bdb042db3c85321346e2894a70f9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8be89bcd7bf5bc0326872bf15216c83b19df6d3f14b2744fa60138e364646c + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b60e0abb01bd15d9cd344d3cdd15c2d5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662b0cf24cc6e33371991db9b3108b9d6b +msg_2_payload= +msg_2_ciphertext=75ef1297edb57f0efa872372675293bc721ecb4f58ee1d87012ff7069f4ff38bca915837e93948a9025a72c5121b0b2b7a1570e1385464d6abf1a2cbc4d84317 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e2c8d3c21594d58f0d7da8d4d40cb0b47ca6b0831e5f8f4ae66966aea4c8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cba677284723c05166976ceb2146d2978e38f17e102780c71cf11416272c8 + +handshake=Noise_XK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254663eea19e1c296b8b49fa9de083783ed78ff77354e0c74a80c28 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b29eebb8f9cd52c9835edda6bcf005b8af266497370cbfc77918 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4324e614b0f53d138eaa88364af70c285c29f6f0a39a9205a67e60c4abe97668cadfa01051a709bff5eae2aac59313848bc983cb75059b3f390193b7a441c87d8dd707dc80571891d57f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7a58f180a45f63401657a7a4817ac5c34dae211e1fbafcb8c42aaccb6c4fd5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e39cc5c38f30dd358deed825a045e77c96c856d9957b5eed88c6704cd113b3 + +handshake=Noise_XKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544063ca1a8f35a6c0d7fb9e4cc482e8a6fde1e919208d6269551a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bbd683767d4eabfb29083fa0b3dd013a95ba81ed9e86311a47b5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e7ee54258e880e01a57de43cacc12c5799e34ed9beb0e3d0d64dfc3d0e1dd0bfc7e980ef5998136bcd7bfbfcaf00cece9dceae07adfa85906cfd90b300640ce55073fea11e49d65b58a7 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d85c66f45b68d04f1317197985ebbd021defdcec3bc7902c940754c7fe7175 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d6b2f036e6cac49e862ccbcbfd359ea858a7c8e3cff228506758633ec53276 + +handshake=Noise_XKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c0e58be3d117a08f563f53f3a5664587644826ada8ee48f341f8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660e4d7c7e528beab538949b0a4dfa1f4e76cedf36a18562938ab5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=5008b6f662503afac70502840b3520d72b641a06dbc77426475b0b83eac6aa1864cb6767a84466710caabc06396c6f0c80bba5482b6c23826fbd1718760e473df19cb475db068c6f27a5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=60abaa1cdd2f173576adcd2f93d5d5737c4ef63598ee3ff6c006a6eb3c9266 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=61261512d684c773a79724182988e8382cd571a3d6aa4703cf1a17a0550204 + +handshake=Noise_XKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c0ff9243a441a9a382292d3a1ef648bb687800b915d240d9ffc8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633ca26c2f74a980f401496b5665615f33b58499e2fdd6e8459cf +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=aa2b2e3078aa0054ca436df384c021f5bef28fbe3a9fb6608fc8f0e5a9a1faff11d841e395a8e26fd37d79d0bcff4df5df12674bfe6a8e2c907ed4286b8b168f2850b7637f300043bd4d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=25ff84a3cb83d33bdf1559428a7d55ff15bdb042db3c85321346e2894a70f9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8be89bcd7bf5bc0326872bf15216c83b19df6d3f14b2744fa60138e364646c + +handshake=Noise_XKpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545137f1f9a9ec7de03e77a2420c1f8a782a7bca8e52b1399c965a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846610ae8c7cae2e22da73ff72bcd1043396c62063feb4d2fe3d51b1 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=75ef1297edb57f0efa872372675293bc721ecb4f58ee1d87012ff7069f4ff38b97ca82a1274c25acfe90da6b5786935e7a7771f21e0af8ae4f3aa4c970e4b172a655b63d8ad90e34e721 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8e2c8d3c21594d58f0d7da8d4d40cb0b47ca6b0831e5f8f4ae66966aea4c8d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6cba677284723c05166976ceb2146d2978e38f17e102780c71cf11416272c8 + +handshake=Noise_IK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bd4f4131b33d738f4a2a299ee097f618811345c8fa0eb3de9fe75154b23f79e215fc093d990c4fa35c77f418515fe85be7f82ea4475e5b11703a89b904e605aa +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846616d4da51a337934aee3e82bab0b7b1f3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b57093f3d1261319399a1150d5a937f3ef1a27415d2f9581d3bc0143eedefe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe045568d1f521838b2eb348e07f26cd10332485732fb821ff8841ccc3b9d1 + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c073edcce60db134899fe51feb700d92514276978d84cd27efe39f2691af2d4a4e00cf64ca504a736cb3ff448a4d8c080ffacdaeaae20f3b1c45ea6126104349 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466977bbfed6c53f8859e41fab61954c171 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=323a0be447f4985589dea6ff8f3f4d27d810be1e96862868332a4ad903a060 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=109670cd7de301fe4d6c3621935bc2d935db08c60b76f7096015ebcb0f5679 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254afb4846f0ab102f56af491cdd2855b8a556936a17ac486c0f6446da6cafb19712c35fb1e5423b76643bb22c685d832c2ebc7bf156bda45e70d222cf1662298cf +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662331a84da0076216b8d52a48f33ca4c3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cb7c2b91b71ce817e0958bed36b5644996d8f2c63e4667627792127def75e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=56320be0ca19a8b310230dca8e09b0002288e86e297286ca5810e913102170 + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625496931a9f8e5df3b9bfb984905e85191f366b770652f2222b7fa15c23eb721eafa6062da36f9201533e196a95894eddf0bedf2a6a3e7d7bf100418c962dcde379 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846624f9e1f6148f690211e6ec55b0f3869c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4a5d72c8e755787497f85fc22c91244a26efe8edb79806caf15e0c128b5e01 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f31be3c70e06897a35d0167821f144b438b6a3fda809f20fca377895727730 + +handshake=Noise_IK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bd4f4131b33d738f4a2a299ee097f618811345c8fa0eb3de9fe75154b23f79e215fc093d990c4fa35c77f418515fe85b718a16e03b74978aee0e5fb0a382318c1438e588b4c6f5fb435e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bca07c8ea8d3db6803fa9cde7f2e8285562927a1503fe8922e8f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b57093f3d1261319399a1150d5a937f3ef1a27415d2f9581d3bc0143eedefe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe045568d1f521838b2eb348e07f26cd10332485732fb821ff8841ccc3b9d1 + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c073edcce60db134899fe51feb700d92514276978d84cd27efe39f2691af2d4a4e00cf64ca504a736cb3ff448a4d8c0867cea5eea88023df452cbd6b03ecc3e05a8fe9bf4255c6622fa4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660fce1dc5223bdd289d0d5e218041462316be826c29ac6ad53228 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=323a0be447f4985589dea6ff8f3f4d27d810be1e96862868332a4ad903a060 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=109670cd7de301fe4d6c3621935bc2d935db08c60b76f7096015ebcb0f5679 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254afb4846f0ab102f56af491cdd2855b8a556936a17ac486c0f6446da6cafb19712c35fb1e5423b76643bb22c685d832c29265090973e176e6ac4c49efeed0b41313413ba672358263aaf6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6edc0252eaef96ad7802d71e982070ec80e6f0a48142a405110 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cb7c2b91b71ce817e0958bed36b5644996d8f2c63e4667627792127def75e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=56320be0ca19a8b310230dca8e09b0002288e86e297286ca5810e913102170 + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625496931a9f8e5df3b9bfb984905e85191f366b770652f2222b7fa15c23eb721eafa6062da36f9201533e196a95894eddf0498cac29da3dc9ae306cf2959f1d510f60b60a555c52e5d4a1db +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf6f8562c58cda4461146db7e93a0dea4f1dc60792564dca6a0e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4a5d72c8e755787497f85fc22c91244a26efe8edb79806caf15e0c128b5e01 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f31be3c70e06897a35d0167821f144b438b6a3fda809f20fca377895727730 + +handshake=Noise_IK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bd4f4131b33d738f4a2a299ee097f618811345c8fa0eb3de9fe75154b23f79e25007dbe6b36cbdfdf4a9cce3f365862218ecd1fdae9317673e275392f9bb54c8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846657ca3004795589e226d50586a9c501ab +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b57093f3d1261319399a1150d5a937f3ef1a27415d2f9581d3bc0143eedefe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe045568d1f521838b2eb348e07f26cd10332485732fb821ff8841ccc3b9d1 + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c073edcce60db134899fe51feb700d92514276978d84cd27efe39f2691af2d4add525786f0b5486403c99532773cf71d38cc92838b0b5546b6ea89dd572bc610 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1a2385682ab40ed7eec1047d6311d6e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=323a0be447f4985589dea6ff8f3f4d27d810be1e96862868332a4ad903a060 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=109670cd7de301fe4d6c3621935bc2d935db08c60b76f7096015ebcb0f5679 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254afb4846f0ab102f56af491cdd2855b8a556936a17ac486c0f6446da6cafb1971afe73d2065190e650c2770cc69910e9c2fb119cda3e97199c7b025201f5af03a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846676715a250c8d851c337934ea53c5cfba +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cb7c2b91b71ce817e0958bed36b5644996d8f2c63e4667627792127def75e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=56320be0ca19a8b310230dca8e09b0002288e86e297286ca5810e913102170 + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625496931a9f8e5df3b9bfb984905e85191f366b770652f2222b7fa15c23eb721eaf0e22fb53171332b0d6d9cbd79d3f14211b141792d05aec8bface5ab036a34ab2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661994f62b38af687a844bb6c574a61ee8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4a5d72c8e755787497f85fc22c91244a26efe8edb79806caf15e0c128b5e01 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f31be3c70e06897a35d0167821f144b438b6a3fda809f20fca377895727730 + +handshake=Noise_IK_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bd4f4131b33d738f4a2a299ee097f618811345c8fa0eb3de9fe75154b23f79e25007dbe6b36cbdfdf4a9cce3f3658622718a16e03b74978aee0e485864a129d991809e531504fe89590e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bca07c8ea8d3db6803fadea87e1a26dd748e73277a458ef6379a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b57093f3d1261319399a1150d5a937f3ef1a27415d2f9581d3bc0143eedefe +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe045568d1f521838b2eb348e07f26cd10332485732fb821ff8841ccc3b9d1 + +handshake=Noise_IKpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c073edcce60db134899fe51feb700d92514276978d84cd27efe39f2691af2d4add525786f0b5486403c99532773cf71d67cea5eea88023df452c1a2188b56660ad8a4a43693fff90497a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660fce1dc5223bdd289d0d0b6dabc844dbacd0c7bc02535162cde6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=323a0be447f4985589dea6ff8f3f4d27d810be1e96862868332a4ad903a060 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=109670cd7de301fe4d6c3621935bc2d935db08c60b76f7096015ebcb0f5679 + +handshake=Noise_IKpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254afb4846f0ab102f56af491cdd2855b8a556936a17ac486c0f6446da6cafb1971afe73d2065190e650c2770cc69910e9c9265090973e176e6ac4cf5cd4db3bf6527f987a742a2c83252d9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6edc0252eaef96ad780ac004ef914e91c2a81181764334ca856 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1cb7c2b91b71ce817e0958bed36b5644996d8f2c63e4667627792127def75e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=56320be0ca19a8b310230dca8e09b0002288e86e297286ca5810e913102170 + +handshake=Noise_IKpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625496931a9f8e5df3b9bfb984905e85191f366b770652f2222b7fa15c23eb721eaf0e22fb53171332b0d6d9cbd79d3f1421498cac29da3dc9ae306c19babad8b3a5f6d7be72eca9272f7667 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf6f8562c58cda446114b33c5291da3398dc9b9485610b524536 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4a5d72c8e755787497f85fc22c91244a26efe8edb79806caf15e0c128b5e01 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f31be3c70e06897a35d0167821f144b438b6a3fda809f20fca377895727730 + +handshake=Noise_XX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c558f251b38f5770b20bfe770709ec1aa6e0aa1a2d8b4485e51667a91055ceed52213b8314b06ae8c63d9c596e2cdcb332ca2b99b3a8a6e7f71d1b1e62340fb3 +msg_2_payload= +msg_2_ciphertext=c0eef7241004fcad6fb84daa25d9a8921a8da60da9b8b39f387667e98069e72fea2a13ea74822183fae1d17df8a490e5ea7ab72edd2bce950758a4482447f664 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bb9dd5494e382306a88f8f32a4bb268cad2632353dd13aad364dc7493c4561 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e5ac356a3234cee842c6f719fa0657d35b69bcfe51e2edf5534c4276b7131 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541eac09194c019139be771f49b620c91c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846641342d97be7d620d656cff580ca58e8f11cc5001702990645cd09164242e8540a93a21344bede93c4d681e24a59314512bfcafee190ed63806ed3fa4b3aa541e +msg_2_payload= +msg_2_ciphertext=2e8196d00b701c2f09f141b1c4ccc47e9dca2922bd2491c34cd76b8c3d337e0841879b74366ade47342c3153e4c3dfef93cd1184d6ea2f44fbed3b705b9c569e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7d2b55d4b79d038d8398d42d75bbf870e77ab1d73ba429e188da7010317c89 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c6c2a7901abf013a515ab87928fb7e7d87207ae956668e0e9795fffc08b25c + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545126b622432ac37eabd44b8b671853ad +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667c40d55b0bfa624fa6b23f02030ffaefe7925a9bd87194f8c4fe9d930dc959ec1d5f0b9d992fd41eb1eec03fe61d1b12fb4812e5f0b96645e5e4769146fa8671 +msg_2_payload= +msg_2_ciphertext=249a8e4d794c3c6df1b51eda2254f2653b19d99d124278a759abe483bb6d7906caadfe742ab3308406c369d18c95def0250afccdc7434602b5b38a1d49c710af +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f5a6516b19d933d6c0a5dc8c0145ce39e9dfac207ff6fa5c654d49bc6b1ab0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73464d1a429f4c20cbeb5d668e17cb5ec4158eea21db21bd2432f8b4733813 + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d08b0eb94fee5f11568817855354556 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662906b946c77f56bfe59790f6704d3506d892dec0ba85771b18f8d371e23e2970e2e534ad4921563e1560ea5696496cc68ca7fcca73011070e324a5d9505b9f6c +msg_2_payload= +msg_2_ciphertext=72cc9fc9a204b27abb198bdf41e73002d1b348de18ca66cd2574193a06fd9c64253f7755e1975ad268d0f0cc6adae8a43bd3dcf7d9246691c31cdf435c0a887d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1dcab75cb31e3e6d0e761090558ef90578435d3543a53ff7abca20ee152a82 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e26d4813675ea40de3cbbf14a4b80e6299422374ef84a3ee6d45b8f0e7b8 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c13ab819ea6ed3499570aef3a388eb8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668e7a60ef8fbfa562e6542a22ef5e4944d733237508bf157ed4492e233b46162085060ee627d35f17b178d9519d9e86802c82d79abc624b8e2a82fb6b5bc0223d +msg_2_payload= +msg_2_ciphertext=16fa408d9a67b448377f6a27288d735f09088bd0493bbab602a0b3608b648138f95c9f1d5651729782ce22578543f6c0e6deb733cdab22a589c91b92d0a79954 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c45aa274ed25812f1a749351bcc6f968d834f8e2bb7008119c58fbe7a9eedd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=53fd1fc7eecbbf238f3b67111f718da5d85381a0de6009a46e5a415e5f75ac + +handshake=Noise_XX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c558f251b38f5770b20bfe770709ec1aa6e0aa1a2d8b4485e51667a91055ceedff4f63d2d8eca379c401e83654b61786843c6dd463d2f588ba12d1d142fceeafa8131dab9e00214566b7 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c0eef7241004fcad6fb84daa25d9a8921a8da60da9b8b39f387667e98069e72f2ac97f4079de25d8760541b7be628fd8427be5ec64387fbf2f983fa7989f88310b47d6d2577980a7d4b9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bb9dd5494e382306a88f8f32a4bb268cad2632353dd13aad364dc7493c4561 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e5ac356a3234cee842c6f719fa0657d35b69bcfe51e2edf5534c4276b7131 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625443dbdf007bb4875a4d95f427ceac82a818307571a82a9888f324 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846641342d97be7d620d656cff580ca58e8f11cc5001702990645cd09164242e8540e4eb0518983a8996373abbfb7c83473780c6f834d01a5e023cf450299ef1a361f11092a75e7d11a1950e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2e8196d00b701c2f09f141b1c4ccc47e9dca2922bd2491c34cd76b8c3d337e0810775c9452ed0bc21fad36d99cd9b325a5a1e299a65623fcf08b62aba10a58909d5c7c1eaa45ed50cf6c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7d2b55d4b79d038d8398d42d75bbf870e77ab1d73ba429e188da7010317c89 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c6c2a7901abf013a515ab87928fb7e7d87207ae956668e0e9795fffc08b25c + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254909b4be38128fa1ee3821ec8256c9961c713bccb82aa844d7d6e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667c40d55b0bfa624fa6b23f02030ffaefe7925a9bd87194f8c4fe9d930dc959ecbfa439481180c1fa2665a4dfc37855fdfae5baae64f2b1cb55fbec0507a6882974c58a4e9ed063d24a59 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=249a8e4d794c3c6df1b51eda2254f2653b19d99d124278a759abe483bb6d79067ded5abf82f76071cc900b5b99e49c2ce2e7127ee75d79d77d23cf7943689beae674993aca9ded6a0581 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f5a6516b19d933d6c0a5dc8c0145ce39e9dfac207ff6fa5c654d49bc6b1ab0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73464d1a429f4c20cbeb5d668e17cb5ec4158eea21db21bd2432f8b4733813 + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d46c611dff6b8421ca04cbf2dc1a71bd2f17e9aca5cb3d47f1e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662906b946c77f56bfe59790f6704d3506d892dec0ba85771b18f8d371e23e2970d9eca6cec4744d6c0d01c4588b8c47becfec6d91b61f265adeb8e7d237be6c4970cf47183143be50cce6 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=72cc9fc9a204b27abb198bdf41e73002d1b348de18ca66cd2574193a06fd9c646ba5b239f740c3f5824d818974348687ed71162b3d3104ca4aa588973e50ce241ccbeb9494a17e72f74c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1dcab75cb31e3e6d0e761090558ef90578435d3543a53ff7abca20ee152a82 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e26d4813675ea40de3cbbf14a4b80e6299422374ef84a3ee6d45b8f0e7b8 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254425bfa36e76a8838d5d964c082e46b0fb8bbee7bb0d8efe882e2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668e7a60ef8fbfa562e6542a22ef5e4944d733237508bf157ed4492e233b461620fcbd9a9234eacd67a25d0ad5a7818bcd53bc6adbd943656eceefd701de1c68ca75ad16693e0205b3f3e5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=16fa408d9a67b448377f6a27288d735f09088bd0493bbab602a0b3608b648138429bf29a9ffe33163d05345fec308712f7c3bb2fffecbdf00ca7d0ede3768f41d5774259f7fd971dc4d4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c45aa274ed25812f1a749351bcc6f968d834f8e2bb7008119c58fbe7a9eedd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=53fd1fc7eecbbf238f3b67111f718da5d85381a0de6009a46e5a415e5f75ac + +handshake=Noise_XX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c558f251b38f5770b20bfe770709ec1aa6e0aa1a2d8b4485e51667a91055ceeddce4ec65c8701bb8e394894acf42ee631f9e735b3cf68b830731abfe45e4c578 +msg_2_payload= +msg_2_ciphertext=c0eef7241004fcad6fb84daa25d9a8921a8da60da9b8b39f387667e98069e72f6e03e7676577b7c2e23edc932cb7269d60ab5a53084cd3cbf9d26bc420f65426 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bb9dd5494e382306a88f8f32a4bb268cad2632353dd13aad364dc7493c4561 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e5ac356a3234cee842c6f719fa0657d35b69bcfe51e2edf5534c4276b7131 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c3e79e8d77ebc7c8096364ee6641264 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846641342d97be7d620d656cff580ca58e8f11cc5001702990645cd09164242e854007095bac0754ea0e3575efa81d8bd1dc73256f79cf94429ec4097a84cefb4ae2 +msg_2_payload= +msg_2_ciphertext=2e8196d00b701c2f09f141b1c4ccc47e9dca2922bd2491c34cd76b8c3d337e08ee24c6f9c32e75df9c0ffee981226a1917a55e32f4dffd80f8c6291883af6de5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7d2b55d4b79d038d8398d42d75bbf870e77ab1d73ba429e188da7010317c89 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c6c2a7901abf013a515ab87928fb7e7d87207ae956668e0e9795fffc08b25c + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d637e75932c13066f7d9ae8202e434e9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667c40d55b0bfa624fa6b23f02030ffaefe7925a9bd87194f8c4fe9d930dc959ec7f0d1d6e6ef7fe8e9d099b7283e8e4c00793986c521afd21ced3bffc6ef3ec23 +msg_2_payload= +msg_2_ciphertext=249a8e4d794c3c6df1b51eda2254f2653b19d99d124278a759abe483bb6d7906bc6104737c7e8072b6b9c1b2742699495e478b0434d240b3989a1d4df21a7009 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f5a6516b19d933d6c0a5dc8c0145ce39e9dfac207ff6fa5c654d49bc6b1ab0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73464d1a429f4c20cbeb5d668e17cb5ec4158eea21db21bd2432f8b4733813 + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543c9c4f5f492c2bd6298624dbc89f8cec +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662906b946c77f56bfe59790f6704d3506d892dec0ba85771b18f8d371e23e297005331f9cf890ae50499c20de44cb81ec82cdda938bc9693f36ed9ea63fa36e44 +msg_2_payload= +msg_2_ciphertext=72cc9fc9a204b27abb198bdf41e73002d1b348de18ca66cd2574193a06fd9c64b71437f9cf75d18d4ee5a748568c35ed76c8a0a7e52917864f65947f8c6950b4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1dcab75cb31e3e6d0e761090558ef90578435d3543a53ff7abca20ee152a82 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e26d4813675ea40de3cbbf14a4b80e6299422374ef84a3ee6d45b8f0e7b8 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549891f0cad0f98f78af16e0c6bfc729d3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668e7a60ef8fbfa562e6542a22ef5e4944d733237508bf157ed4492e233b461620eea5a18ee7d4c6aebc3be1649b7c94aff64dcd3aac9bc1ca5e4419d281669075 +msg_2_payload= +msg_2_ciphertext=16fa408d9a67b448377f6a27288d735f09088bd0493bbab602a0b3608b64813893f6fdc1de28aa54d076a1cf4b3e86ef9c6348a34f8ecddb9c3797184ffb4d08 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c45aa274ed25812f1a749351bcc6f968d834f8e2bb7008119c58fbe7a9eedd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=53fd1fc7eecbbf238f3b67111f718da5d85381a0de6009a46e5a415e5f75ac + +handshake=Noise_XX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c558f251b38f5770b20bfe770709ec1aa6e0aa1a2d8b4485e51667a91055ceed9c32712c57e5aa04f65932b60b4c6064843c6dd463d2f588ba128cd76050bb6209711df3294879ad0e11 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c0eef7241004fcad6fb84daa25d9a8921a8da60da9b8b39f387667e98069e72f9bd63447f97b7741e373ebbf9015ddd9427be5ec64387fbf2f98ea4a70997c58ecb2fe807114cabb46ae +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bb9dd5494e382306a88f8f32a4bb268cad2632353dd13aad364dc7493c4561 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e5ac356a3234cee842c6f719fa0657d35b69bcfe51e2edf5534c4276b7131 + +handshake=Noise_XXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625443dbdf007bb4875a4d95a73282156c90715757356ed75e725b2b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846641342d97be7d620d656cff580ca58e8f11cc5001702990645cd09164242e8540661edb60a6a8540e6c5e82f0bd95ab8b80c6f834d01a5e023cf46b51e3b2c9796244f4791c4f4c2ad9f7 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2e8196d00b701c2f09f141b1c4ccc47e9dca2922bd2491c34cd76b8c3d337e08d7d5063ef629525d81a06e1ad0e8ce06a5a1e299a65623fcf08b6be25d3c554898997726450ccbb56652 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7d2b55d4b79d038d8398d42d75bbf870e77ab1d73ba429e188da7010317c89 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c6c2a7901abf013a515ab87928fb7e7d87207ae956668e0e9795fffc08b25c + +handshake=Noise_XXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254909b4be38128fa1ee382b46bfbe2630124202d4749ea2d06487d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667c40d55b0bfa624fa6b23f02030ffaefe7925a9bd87194f8c4fe9d930dc959ec216aa6b7d41596b4f9e4905f412771befae5baae64f2b1cb55fbae113857fc75634d33125ef64c8515c5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=249a8e4d794c3c6df1b51eda2254f2653b19d99d124278a759abe483bb6d7906375331eb14a43a9eed6ab1c848203e14e2e7127ee75d79d77d23068fe13e799ae21be2a6521f159608b9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f5a6516b19d933d6c0a5dc8c0145ce39e9dfac207ff6fa5c654d49bc6b1ab0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=73464d1a429f4c20cbeb5d668e17cb5ec4158eea21db21bd2432f8b4733813 + +handshake=Noise_XXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d46c611dff6b8421ca09dc79567842ed38928256a9a35128c20 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662906b946c77f56bfe59790f6704d3506d892dec0ba85771b18f8d371e23e2970c8bc8b2a9fcbe96bcaf5dbb53d958841cfec6d91b61f265adeb8b93fde4f1c6d12a5a66fbd65265c67af +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=72cc9fc9a204b27abb198bdf41e73002d1b348de18ca66cd2574193a06fd9c64aa0e01924994fa145ddb10417d16aa53ed71162b3d3104ca4aa578762e51724a97e08b1762d715c7f9c0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1dcab75cb31e3e6d0e761090558ef90578435d3543a53ff7abca20ee152a82 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=86e26d4813675ea40de3cbbf14a4b80e6299422374ef84a3ee6d45b8f0e7b8 + +handshake=Noise_XXpsk3_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254425bfa36e76a8838d5d9f71f26594bce0a57407a4b1760b814ee +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668e7a60ef8fbfa562e6542a22ef5e4944d733237508bf157ed4492e233b461620be67b52b7bd6053e7767ac64fd91e8df53bc6adbd943656eceef1daadc583828bf9580dc9229e5f87205 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=16fa408d9a67b448377f6a27288d735f09088bd0493bbab602a0b3608b6481380c5cf5a0a5a5b91aa942222b90b489a8f7c3bb2fffecbdf00ca7642bb47f1258177d174797f4d9846494 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c45aa274ed25812f1a749351bcc6f968d834f8e2bb7008119c58fbe7a9eedd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=53fd1fc7eecbbf238f3b67111f718da5d85381a0de6009a46e5a415e5f75ac + +handshake=Noise_IX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466001a448f30a50045a3773283db2513353903f4e248a9b3e2b5c24afb272fe857d7489eb482f3634ac012c7f90637184f3c37d3bbb3cc1741696ea3e8780db3dc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=121b6531c524e613f3b3cfbb08e2c23c11c43ac1715e9f074f01a4fd038e1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1f24c3924ad3d79ceca2efb690500b560e43de2cbc367e1deeecfd983b270b + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549d7ce1d656b5eb9151fba77523378e964f2a8ef91720a611902132d691741271c3d3307b904253d8254a28d98887e407b04239c1c15396fb45fcaa651bb12bf1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666133c831594ab52216dd0807616b26056d0e80f5f6d8fa91fe77e5060db7db9506ef4df925af2c7834a634db720a835ea0afd35264770fa0ce4a40ffc2f3a45b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=39b2227addce43c4691d21674f9695c6a09b112c8222b306075e9515e2c867 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6b01cb18b13f46a8816cdaeac1e8dd93f014affb39fa763aaeebf771b43de4 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625468f5566d63685e265e45046bc696c9c9f0bebd8cf1052c95805155d8c0ee4db5cba654e668d672097727bedb322262c15da304f0ff23ecd5e0bacfd141a2a1e7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c84ed22bb5a1c2a86915757631e35fb2eca787ddbcdc8ea4bc4e20a1f5887efd0a7b4ba3ca44e42bdd7c2ceacda3c85a5dce29603d296ae093a193bf17a4c46a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c49de16ee26037dfe6b9b489f9786a584f44b08821bb5dab44b0e371f6e26 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8771d4351bfa2cb24c5497b8c5a6f5a01a29bd27056c00a29617c7f625689f + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fb6c82215400d2057e6eaa9938cbc77e3fa904df7d3a80b104eff6484b5eb2f92c52ff4d51ef8590bf8b3c7e42ccaf36f5203e5b6cc1255385dd1f7edf0b20a1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aba779821e4e49f52ea4e5fb0ffb8788943f1e50d4fec498230f3d22f119831af4fd75ac2f666d09c5840305632216f6193fdc63d5648e114fa44662ae78d9a7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7af8e7b931417440cdea7240873bf94dd43a92641167a9f984560f56481ea4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=69a6c04db91b2a176d92b6c51b47f5b476e7ae15302e4782e0bc4c7e1b37ae + +handshake=Noise_IX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466001a448f30a50045a3773283db2513353903f4e248a9b3e2b5c24afb272fe8577b273d51b51d4b8ca49ad87e8e1b52025713f6ad6dc975e0f86b25a35b74fc3555e1c91994f94c043080 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=121b6531c524e613f3b3cfbb08e2c23c11c43ac1715e9f074f01a4fd038e1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1f24c3924ad3d79ceca2efb690500b560e43de2cbc367e1deeecfd983b270b + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549d7ce1d656b5eb9151fba77523378e964f2a8ef91720a611902132d691741271c3d3307b904253d8254a28d98887e407a44b0c1e24a560d89e223072156a69a1fb99a798d1683d6e9674 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666133c831594ab52216dd0807616b26056d0e80f5f6d8fa91fe77e5060db7db959c490fe4c98dec54c73b93b3f3150aa522d0889bee5a6675b46a219b8c197bd38a409b0319cb18d13ae4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=39b2227addce43c4691d21674f9695c6a09b112c8222b306075e9515e2c867 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6b01cb18b13f46a8816cdaeac1e8dd93f014affb39fa763aaeebf771b43de4 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625468f5566d63685e265e45046bc696c9c9f0bebd8cf1052c95805155d8c0ee4db5cba654e668d672097727bedb322262c19b4d7142a128929d49c3b558f781c4bf9189d05b178cc7a04ca2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c84ed22bb5a1c2a86915757631e35fb2eca787ddbcdc8ea4bc4e20a1f5887efd9c442f3f6e1e52cf41e96a7b85d31a56bc3b2c8d31f40ca8ac16064518b495caba81820a1c73ba43f2d4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c49de16ee26037dfe6b9b489f9786a584f44b08821bb5dab44b0e371f6e26 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8771d4351bfa2cb24c5497b8c5a6f5a01a29bd27056c00a29617c7f625689f + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fb6c82215400d2057e6eaa9938cbc77e3fa904df7d3a80b104eff6484b5eb2f92c52ff4d51ef8590bf8b3c7e42ccaf367f8e9c43fadcbe94ec0166219dfa665bf065f286bf0d7684aed6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aba779821e4e49f52ea4e5fb0ffb8788943f1e50d4fec498230f3d22f119831a81a9001883959687765f997fcf2e6880f3da82537df7241288faa0075350c178c7a4651dd554b2aeb564 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7af8e7b931417440cdea7240873bf94dd43a92641167a9f984560f56481ea4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=69a6c04db91b2a176d92b6c51b47f5b476e7ae15302e4782e0bc4c7e1b37ae + +handshake=Noise_IX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466001a448f30a50045a3773283db2513353903f4e248a9b3e2b5c24afb272fe857972736c91937300c3a33d0f45f84967554fbd34e74a3ed2da8aa7b187755c58a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=121b6531c524e613f3b3cfbb08e2c23c11c43ac1715e9f074f01a4fd038e1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1f24c3924ad3d79ceca2efb690500b560e43de2cbc367e1deeecfd983b270b + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549d7ce1d656b5eb9151fba77523378e964f2a8ef91720a611902132d691741271d228ca8491bbf257394442a722a705173bbe4efea8677818654b390540df1a18 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666133c831594ab52216dd0807616b26056d0e80f5f6d8fa91fe77e5060db7db959871017b10f8c4b3f1042d2d2932b77bfbb57f9756768ad417cd6f7b111a57e3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=39b2227addce43c4691d21674f9695c6a09b112c8222b306075e9515e2c867 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6b01cb18b13f46a8816cdaeac1e8dd93f014affb39fa763aaeebf771b43de4 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625468f5566d63685e265e45046bc696c9c9f0bebd8cf1052c95805155d8c0ee4db525fa6858eff76b69343b28ced0e7ba02e849f7f3fa7ff70d856f2b3a18a127cd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c84ed22bb5a1c2a86915757631e35fb2eca787ddbcdc8ea4bc4e20a1f5887efda53329c4f4b7540d09ad79bbc106dc0513cce4751ea0b78fef76ccd03cbbb3d8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c49de16ee26037dfe6b9b489f9786a584f44b08821bb5dab44b0e371f6e26 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8771d4351bfa2cb24c5497b8c5a6f5a01a29bd27056c00a29617c7f625689f + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fb6c82215400d2057e6eaa9938cbc77e3fa904df7d3a80b104eff6484b5eb2f925cc71907dbef4fd4df1218a622a5b54a6eeaa63623e51a50e9cc6b5a65f2230 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aba779821e4e49f52ea4e5fb0ffb8788943f1e50d4fec498230f3d22f119831aafd335e73319c4c1d0b67c713fed38346e88c2f18e65fdf3ac90a5a703d753ed +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7af8e7b931417440cdea7240873bf94dd43a92641167a9f984560f56481ea4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=69a6c04db91b2a176d92b6c51b47f5b476e7ae15302e4782e0bc4c7e1b37ae + +handshake=Noise_IX_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466001a448f30a50045a3773283db2513353903f4e248a9b3e2b5c24afb272fe857fb091b2195012c08b0b140bc35cb12735713f6ad6dc975e0f86b731f028f7626e597b40d8649f718297c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=121b6531c524e613f3b3cfbb08e2c23c11c43ac1715e9f074f01a4fd038e1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1f24c3924ad3d79ceca2efb690500b560e43de2cbc367e1deeecfd983b270b + +handshake=Noise_IXpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549d7ce1d656b5eb9151fba77523378e964f2a8ef91720a611902132d691741271d228ca8491bbf257394442a722a70517a44b0c1e24a560d89e225feaed436f2e1b4ebf905774414df4f8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666133c831594ab52216dd0807616b26056d0e80f5f6d8fa91fe77e5060db7db954fd203f0c9d25c3e926672269f2dbe4722d0889bee5a6675b46a801f7f1978b39a17e75bc3505313a9d6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=39b2227addce43c4691d21674f9695c6a09b112c8222b306075e9515e2c867 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6b01cb18b13f46a8816cdaeac1e8dd93f014affb39fa763aaeebf771b43de4 + +handshake=Noise_IXpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625468f5566d63685e265e45046bc696c9c9f0bebd8cf1052c95805155d8c0ee4db525fa6858eff76b69343b28ced0e7ba029b4d7142a128929d49c31c75b3d55df3ac834bd50fc48e781bc5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c84ed22bb5a1c2a86915757631e35fb2eca787ddbcdc8ea4bc4e20a1f5887efd81f8705b7fd1ac44e0db631f6498740ebc3b2c8d31f40ca8ac163346c04b5cc1dcbe242c18dfde5322eb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3c49de16ee26037dfe6b9b489f9786a584f44b08821bb5dab44b0e371f6e26 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8771d4351bfa2cb24c5497b8c5a6f5a01a29bd27056c00a29617c7f625689f + +handshake=Noise_IXpsk2_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fb6c82215400d2057e6eaa9938cbc77e3fa904df7d3a80b104eff6484b5eb2f925cc71907dbef4fd4df1218a622a5b547f8e9c43fadcbe94ec013ac799c77b3b0a6a8dcd4a311473ee22 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aba779821e4e49f52ea4e5fb0ffb8788943f1e50d4fec498230f3d22f119831a48658943f9d91741e1a33103e775e920f3da82537df7241288fab18a128e3c84939f20abf92374bef607 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7af8e7b931417440cdea7240873bf94dd43a92641167a9f984560f56481ea4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=69a6c04db91b2a176d92b6c51b47f5b476e7ae15302e4782e0bc4c7e1b37ae + +handshake=Noise_N_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f79dccb3aa4d5b94432bafca11574ed +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6c123bcb14329bcb133fce1b378e7b3b46e2d98b58e3dae5bf6ef38f77d2a5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e1891da8d5c3333d5c4e85dc726a52356d2908013a234f353acb3922a9230 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254345e04d65d31b4503b548304455bbd46 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d634a8f886d4f0d9ed43ca28dae0b7dbe47f19dfd6fb51cd16e66be0213c8e +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=33775b15e461621ce9a5e20c50221231d8e230484d44e2c37438200771bfbb + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fe78ed820f4450ab1348aad583dda57e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=79568cdbca6a38933f2240f37ce995f44ec540f8a3ab1e31c66da6bfe8b0eb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ff319a896146cb627b7e9bcc087307ab7b5cd09b675fc762fefdb743eefef3 + +handshake=Noise_N_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625442f641b74b61890f33bd3becef41f81f69923bf63c60b1cc6231 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6c123bcb14329bcb133fce1b378e7b3b46e2d98b58e3dae5bf6ef38f77d2a5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e1891da8d5c3333d5c4e85dc726a52356d2908013a234f353acb3922a9230 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f3f4ecd437c593a22cfb64af15662f4bd7e6ef03a841d0260e66 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d634a8f886d4f0d9ed43ca28dae0b7dbe47f19dfd6fb51cd16e66be0213c8e +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=33775b15e461621ce9a5e20c50221231d8e230484d44e2c37438200771bfbb + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254619e5aa215267f135b43473fcae9566b9e67882d44789b29e9da +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=79568cdbca6a38933f2240f37ce995f44ec540f8a3ab1e31c66da6bfe8b0eb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ff319a896146cb627b7e9bcc087307ab7b5cd09b675fc762fefdb743eefef3 + +handshake=Noise_N_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547c2d612458dea09c1056ae723f545f1f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6c123bcb14329bcb133fce1b378e7b3b46e2d98b58e3dae5bf6ef38f77d2a5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e1891da8d5c3333d5c4e85dc726a52356d2908013a234f353acb3922a9230 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a12e1251ccb886f1d3d363a48195a860 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d634a8f886d4f0d9ed43ca28dae0b7dbe47f19dfd6fb51cd16e66be0213c8e +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=33775b15e461621ce9a5e20c50221231d8e230484d44e2c37438200771bfbb + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b5f9c84b3c1c392a387aa90ed926280 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=79568cdbca6a38933f2240f37ce995f44ec540f8a3ab1e31c66da6bfe8b0eb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ff319a896146cb627b7e9bcc087307ab7b5cd09b675fc762fefdb743eefef3 + +handshake=Noise_N_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625442f641b74b61890f33bd4391759de0d03df2ad8026a68f4190b0 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6c123bcb14329bcb133fce1b378e7b3b46e2d98b58e3dae5bf6ef38f77d2a5 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e1891da8d5c3333d5c4e85dc726a52356d2908013a234f353acb3922a9230 + +handshake=Noise_Npsk0_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f3f4ecd437c593a22cfb0bac55293cc03f1617a481ede42ab62b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d634a8f886d4f0d9ed43ca28dae0b7dbe47f19dfd6fb51cd16e66be0213c8e +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=33775b15e461621ce9a5e20c50221231d8e230484d44e2c37438200771bfbb + +handshake=Noise_Npsk1_25519_AESGCM_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254619e5aa215267f135b435e993029733e9d969d29343938c1b1df +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=79568cdbca6a38933f2240f37ce995f44ec540f8a3ab1e31c66da6bfe8b0eb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ff319a896146cb627b7e9bcc087307ab7b5cd09b675fc762fefdb743eefef3 + +handshake=Noise_K_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625438e26a348a6cfdbcb07102e8e5091989 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b9d11027b8d5c0684f197d3d013eb85af4156198273288daeef8221e3b9a4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=74c2881e55dcbee999ade00f6c433a35d60371a3cf651bc1c5617cc397cb87 + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bbc991897e496d88cc4713aa52d34443 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=11f82fb066f3635d85a8f9a98ea5b67c400485a089a4abb74834e2e5a57f4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=eb8febbc984e0c0b8d92d59025912cbed4c7a5986a0c1ee61dbc64565f3228 + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b9bdef6f6b2b03db5c430f4eea428fd +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2ea39abe8e5e7dde6c727f9a970b1cc5f0db6c5825feb620dc4e40fefea543 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8018b274983cbc58f5036d2ce8c0d8833634c86b0d85bd6a038a8036e0621d + +handshake=Noise_K_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6608d0e457383df16f84fb3a03c9d986dfd2441f69eab6586e9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b9d11027b8d5c0684f197d3d013eb85af4156198273288daeef8221e3b9a4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=74c2881e55dcbee999ade00f6c433a35d60371a3cf651bc1c5617cc397cb87 + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625408d9b97427847c9e21cfa5fa926792c424bac2922df0b6719ca4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=11f82fb066f3635d85a8f9a98ea5b67c400485a089a4abb74834e2e5a57f4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=eb8febbc984e0c0b8d92d59025912cbed4c7a5986a0c1ee61dbc64565f3228 + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547fefbe317b025d36f640f51d6d0ab59af487b829a06968eda96c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2ea39abe8e5e7dde6c727f9a970b1cc5f0db6c5825feb620dc4e40fefea543 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8018b274983cbc58f5036d2ce8c0d8833634c86b0d85bd6a038a8036e0621d + +handshake=Noise_K_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254176d7116aaeb842d6dcf237932eccf03 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b9d11027b8d5c0684f197d3d013eb85af4156198273288daeef8221e3b9a4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=74c2881e55dcbee999ade00f6c433a35d60371a3cf651bc1c5617cc397cb87 + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c610aa4b7520958544adaf4375afc3de +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=11f82fb066f3635d85a8f9a98ea5b67c400485a089a4abb74834e2e5a57f4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=eb8febbc984e0c0b8d92d59025912cbed4c7a5986a0c1ee61dbc64565f3228 + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625499a8f592f261e9b5339c8f477cc9c16c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2ea39abe8e5e7dde6c727f9a970b1cc5f0db6c5825feb620dc4e40fefea543 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8018b274983cbc58f5036d2ce8c0d8833634c86b0d85bd6a038a8036e0621d + +handshake=Noise_K_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6608d0e457383df16f88fad0f657acae9f22fe892786cb660b2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b9d11027b8d5c0684f197d3d013eb85af4156198273288daeef8221e3b9a4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=74c2881e55dcbee999ade00f6c433a35d60371a3cf651bc1c5617cc397cb87 + +handshake=Noise_Kpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625408d9b97427847c9e21cf912833fff74a652fa343036dfb1b41ea +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=11f82fb066f3635d85a8f9a98ea5b67c400485a089a4abb74834e2e5a57f4d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=eb8febbc984e0c0b8d92d59025912cbed4c7a5986a0c1ee61dbc64565f3228 + +handshake=Noise_Kpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547fefbe317b025d36f6408925984d138fde176f4a9733c7706df9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2ea39abe8e5e7dde6c727f9a970b1cc5f0db6c5825feb620dc4e40fefea543 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8018b274983cbc58f5036d2ce8c0d8833634c86b0d85bd6a038a8036e0621d + +handshake=Noise_X_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545730809282cfc06c3f895a7660f5bb7725583f11e5566e698a972505841076fd193070f26567584ddb9a11f44c37722efa4689cece4fd7b57371b7aa56233e27 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=458838a0dd2fb593e0264aa8f65ecf54a29227215742be16065db5a9e64ae0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ce36ae61d167896842a9117b31ed88845c34ea868ce4f99075df0eb388dbbe + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541401f93c17b8761a54f7a233e20fae86a9858038716057a8a1376d708c390e5c8395e377b11f0ebc06500cc47602c4c7a4f348296b28740fe8b5e84a8c02db6c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1085833cf5bcf7446d55ec7a8a07af2752b57b729e2dd6ca882b946d00b4fe +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bcbb6258caa407556855bf3236705c6f24003ebb2c79ba707afef937cfadcd + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447657edc39b8a745cd59d07d6e5a2c003c7f9b3e3643af88ca131edbc5578f4a636583b0b613417ec497846b87dfa005cc61f92786e7692362934a0eed2484c4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0843a331ef88666075f33de5baa1a3cb426f0d4b16de1ff591a6f2e467d07b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a6edf21b63c3d67b27e4235f7c6249153c182cb5fd0bab4e2113c4aecc4017 + +handshake=Noise_X_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545730809282cfc06c3f895a7660f5bb7725583f11e5566e698a972505841076fd193070f26567584ddb9a11f44c37722e155570cd162d7626fdd606a44acba5181f943a9576dc6c0787cb +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=458838a0dd2fb593e0264aa8f65ecf54a29227215742be16065db5a9e64ae0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ce36ae61d167896842a9117b31ed88845c34ea868ce4f99075df0eb388dbbe + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541401f93c17b8761a54f7a233e20fae86a9858038716057a8a1376d708c390e5c8395e377b11f0ebc06500cc47602c4c755841fd865669d89825061d5fca07ba66ed0abc4f4218f4d6899 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1085833cf5bcf7446d55ec7a8a07af2752b57b729e2dd6ca882b946d00b4fe +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bcbb6258caa407556855bf3236705c6f24003ebb2c79ba707afef937cfadcd + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447657edc39b8a745cd59d07d6e5a2c003c7f9b3e3643af88ca131edbc5578f4a636583b0b613417ec497846b87dfa00568b6e7db7a7e3dd0e5ab3dc13a2e726a95e9487330354b79556a +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0843a331ef88666075f33de5baa1a3cb426f0d4b16de1ff591a6f2e467d07b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a6edf21b63c3d67b27e4235f7c6249153c182cb5fd0bab4e2113c4aecc4017 + +handshake=Noise_X_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545730809282cfc06c3f895a7660f5bb7725583f11e5566e698a972505841076fd287c0bb778052148eed1a556d5a39611dac85f63cdb36c055a0b62f0488fb1eb +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=458838a0dd2fb593e0264aa8f65ecf54a29227215742be16065db5a9e64ae0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ce36ae61d167896842a9117b31ed88845c34ea868ce4f99075df0eb388dbbe + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541401f93c17b8761a54f7a233e20fae86a9858038716057a8a1376d708c390e5ca20d0296245bd7bde6f607b09dcb7b244553d8e657f7683cd076f4dda56f8300 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1085833cf5bcf7446d55ec7a8a07af2752b57b729e2dd6ca882b946d00b4fe +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bcbb6258caa407556855bf3236705c6f24003ebb2c79ba707afef937cfadcd + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447657edc39b8a745cd59d07d6e5a2c003c7f9b3e3643af88ca131edbc5578f4a3d88a7587a88291fced6580a9485994229bf2b68b22e0364494c2ce92e253ffa +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0843a331ef88666075f33de5baa1a3cb426f0d4b16de1ff591a6f2e467d07b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a6edf21b63c3d67b27e4235f7c6249153c182cb5fd0bab4e2113c4aecc4017 + +handshake=Noise_X_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545730809282cfc06c3f895a7660f5bb7725583f11e5566e698a972505841076fd287c0bb778052148eed1a556d5a39611155570cd162d7626fdd63547ad497b220e81b9ff2557f057f698 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=458838a0dd2fb593e0264aa8f65ecf54a29227215742be16065db5a9e64ae0 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=ce36ae61d167896842a9117b31ed88845c34ea868ce4f99075df0eb388dbbe + +handshake=Noise_Xpsk0_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541401f93c17b8761a54f7a233e20fae86a9858038716057a8a1376d708c390e5ca20d0296245bd7bde6f607b09dcb7b2455841fd865669d8982503fad6c369df182f624375e02b6537b80 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=1085833cf5bcf7446d55ec7a8a07af2752b57b729e2dd6ca882b946d00b4fe +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bcbb6258caa407556855bf3236705c6f24003ebb2c79ba707afef937cfadcd + +handshake=Noise_Xpsk1_25519_AESGCM_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447657edc39b8a745cd59d07d6e5a2c003c7f9b3e3643af88ca131edbc5578f4a3d88a7587a88291fced6580a9485994268b6e7db7a7e3dd0e5ab679b5d4402ec2c50e88cda1c46aa7811 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=0843a331ef88666075f33de5baa1a3cb426f0d4b16de1ff591a6f2e467d07b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a6edf21b63c3d67b27e4235f7c6249153c182cb5fd0bab4e2113c4aecc4017 + +handshake=Noise_NN_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b9a74f6724441623af038022288c2556 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96cd46be111804586a935795eeb4ce62bdec121048a10520b00266b22722eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe2bc534e31964c0bd56337223e921565e39dbc5f156aa04766ced4689a2a2 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e7136508cb8178281204abd62e9f2a3e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466922f3b7824001193c077abd8b7a73030 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b349a522c145762c7c737ac1d1425ce1fb25c7cca626177ee4ceed3cd6fb3d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b41e24399dc3f1ad2faf82868700e4bf31bb89f6616e1d6a92802bb8ad80d6 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ee9d033f6e676839de40170aca012002 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fa780f5014acbab4d9e8a60099774b2f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c86e1615188d3feae514a908523ccbbce6f0b0fa368c0dbac6ddf01b6571 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3b27b0caca5899086a3ebfb80a0651a18f1af75c9f71f3b3818a0170c8e615 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254649f81a8f7cd2ee213caf437abedbbf5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f61e2ebde3648ba1353298a7b8f99454 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eb1a9999225c8a03f6c053d24da26df330c7b2ac6315c5aeff9a4c2893d9e3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=17aecb7454199636aa7e8a44b7e51b5dc6729b39faddd2739bc66d8cbf07be + +handshake=Noise_NN_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb598b7e636e9475d9a7d3111d7a7f3929f0f4c47293613c173f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96cd46be111804586a935795eeb4ce62bdec121048a10520b00266b22722eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe2bc534e31964c0bd56337223e921565e39dbc5f156aa04766ced4689a2a2 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547c78f22f8cea986f934a675201c7f431a539e50c9be46986fa89 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666913ea64c74c2f63ee5e814fda25301b9508e4685ee02e9852fd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b349a522c145762c7c737ac1d1425ce1fb25c7cca626177ee4ceed3cd6fb3d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b41e24399dc3f1ad2faf82868700e4bf31bb89f6616e1d6a92802bb8ad80d6 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d14f69b3b9d75ea1662d0ce4daecd3845bd11582aebf2fba3e99 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466961705fd812d19815374d102e749b09e623ad659a7a3afef8415 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c86e1615188d3feae514a908523ccbbce6f0b0fa368c0dbac6ddf01b6571 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3b27b0caca5899086a3ebfb80a0651a18f1af75c9f71f3b3818a0170c8e615 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ba71add3db8e76dddcfecd52c7db8b92e7b993407c57d909b7f9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665aeaba3e8ae057890d222d19af245e23209100a4b501ca82f843 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eb1a9999225c8a03f6c053d24da26df330c7b2ac6315c5aeff9a4c2893d9e3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=17aecb7454199636aa7e8a44b7e51b5dc6729b39faddd2739bc66d8cbf07be + +handshake=Noise_NN_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665cda04f69d491f9bf509e632fc1a20dd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96cd46be111804586a935795eeb4ce62bdec121048a10520b00266b22722eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe2bc534e31964c0bd56337223e921565e39dbc5f156aa04766ced4689a2a2 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546e96a20116b68fd776478e81d11779ca +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666f51bc44f88917daa53fb4529499b55 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b349a522c145762c7c737ac1d1425ce1fb25c7cca626177ee4ceed3cd6fb3d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b41e24399dc3f1ad2faf82868700e4bf31bb89f6616e1d6a92802bb8ad80d6 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545860fa411dfa26d26f2128f7e347eaf9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662d6b25a63eb7741de46ecfe91e243f6f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c86e1615188d3feae514a908523ccbbce6f0b0fa368c0dbac6ddf01b6571 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3b27b0caca5899086a3ebfb80a0651a18f1af75c9f71f3b3818a0170c8e615 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254358bf186163f6d621580cf909c191a7c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b382c809faae2b2874cd218c7b075c96 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eb1a9999225c8a03f6c053d24da26df330c7b2ac6315c5aeff9a4c2893d9e3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=17aecb7454199636aa7e8a44b7e51b5dc6729b39faddd2739bc66d8cbf07be + +handshake=Noise_NN_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb598b7e636e9475d9a74243a419c31324b40cc77cc7a7ea3b24 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96cd46be111804586a935795eeb4ce62bdec121048a10520b00266b22722eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fe2bc534e31964c0bd56337223e921565e39dbc5f156aa04766ced4689a2a2 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547c78f22f8cea986f934ab17c2484a24a990a6473d588a4f20e99 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666913ea64c74c2f63ee5e32a5358320d459322d624c9ccc975fa0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b349a522c145762c7c737ac1d1425ce1fb25c7cca626177ee4ceed3cd6fb3d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b41e24399dc3f1ad2faf82868700e4bf31bb89f6616e1d6a92802bb8ad80d6 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d14f69b3b9d75ea1662d338ce00a4c4454f04db11957c29b45ba +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466961705fd812d198153745358e4e1e28b5a350b1f7abd0f271620 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=75c86e1615188d3feae514a908523ccbbce6f0b0fa368c0dbac6ddf01b6571 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3b27b0caca5899086a3ebfb80a0651a18f1af75c9f71f3b3818a0170c8e615 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA256 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ba71add3db8e76dddcfe83087861219e26e6f5b0b682e6758cdd +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665aeaba3e8ae057890d221b12297799709eb36b11f4fd7366a4b2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=eb1a9999225c8a03f6c053d24da26df330c7b2ac6315c5aeff9a4c2893d9e3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=17aecb7454199636aa7e8a44b7e51b5dc6729b39faddd2739bc66d8cbf07be + +handshake=Noise_KN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f99627c2b9a34dc2e78efc21ea6d09e0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=440ade028b567ce045b4a367bc7644ba49ff120f2e704abe4be8ce31a43c0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=644df69c08e6c5b832b7b34b54a7e616efc276686ea257ca570c7b0af25e03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549d36baa6dbd5bae534893a1691872bff +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eec752b6d790962a0adb9fa92948a16f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58d034db684b5b9548fa8a2596d5ef48bdc0827f3c936757f824f25190410c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5987d3cbe26bcf75946a86d0555108608e7ed18325dd60fe7d4fd200ee741d + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545c1042a1c7e8f74e1c96e053fc8ca7d4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466458d2cdf33b1fbee339147985abf0afa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7474619bc60a98042cc7bce09f4f631f20af421de18fc434457e2fb7f9e48e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00783db976d144d85fb4dbb341e908748eb0bc90123fcf4162b10cd34277ef + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c91264cfdb8fc6b8804d45a55b62a8b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846696ab554cdc752c12efb617a2bbb548d0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d65a6ebbe3f38a2f2de8529b5203ed2668cbcefc48219fce3f2414bf3b2bdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cdef5b6bd32cdca6ebfe2a3b697caadc3099b9e820eb1c9d27d28b6ed99138 + +handshake=Noise_KN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c39ce1d8e1bc7d551d60e0f13021b569aaf063bbfbaeb5df1d48 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=440ade028b567ce045b4a367bc7644ba49ff120f2e704abe4be8ce31a43c0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=644df69c08e6c5b832b7b34b54a7e616efc276686ea257ca570c7b0af25e03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d9e492b73ab5e7b411ca24b530505ed9f9a7434b7fb9e3942543 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466faed543a83225ae87e5f7b9ed811dd5a5bea64334ddf210e18b4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58d034db684b5b9548fa8a2596d5ef48bdc0827f3c936757f824f25190410c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5987d3cbe26bcf75946a86d0555108608e7ed18325dd60fe7d4fd200ee741d + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b78fe393615d3918bb58f0884d2d372e53e4851ce80e67fe922 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466273122b0e5f91c8b4a7ef2d5a964eb79bc00a41011e068557be1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7474619bc60a98042cc7bce09f4f631f20af421de18fc434457e2fb7f9e48e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00783db976d144d85fb4dbb341e908748eb0bc90123fcf4162b10cd34277ef + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d738849e4f8635b57bf99e438b655ab0cdd92b50c3eb8a38fa47 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466874006ee8e970d1140a893ddd52de47e27b95d0f17bd424122fd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d65a6ebbe3f38a2f2de8529b5203ed2668cbcefc48219fce3f2414bf3b2bdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cdef5b6bd32cdca6ebfe2a3b697caadc3099b9e820eb1c9d27d28b6ed99138 + +handshake=Noise_KN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f658a41f0ba1afd9c3df2bc05eb14e0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=440ade028b567ce045b4a367bc7644ba49ff120f2e704abe4be8ce31a43c0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=644df69c08e6c5b832b7b34b54a7e616efc276686ea257ca570c7b0af25e03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544914ec3c41b58c96b596001a8abe3938 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668f00eba16f40a2355d414ed7b0bab565 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58d034db684b5b9548fa8a2596d5ef48bdc0827f3c936757f824f25190410c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5987d3cbe26bcf75946a86d0555108608e7ed18325dd60fe7d4fd200ee741d + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a01257cd75ea9e8e2fe8a59205962271 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846680d63539016c3cf1e09fe3440be095d6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7474619bc60a98042cc7bce09f4f631f20af421de18fc434457e2fb7f9e48e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00783db976d144d85fb4dbb341e908748eb0bc90123fcf4162b10cd34277ef + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254677a7c6247070ec793bfa8ea24a40134 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466931ff9b08ae6a9b92eab49565d39c990 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d65a6ebbe3f38a2f2de8529b5203ed2668cbcefc48219fce3f2414bf3b2bdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cdef5b6bd32cdca6ebfe2a3b697caadc3099b9e820eb1c9d27d28b6ed99138 + +handshake=Noise_KN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c39ce1d8e1bc7d551d6096fc00a1fb421a5a36483878f3112caa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=440ade028b567ce045b4a367bc7644ba49ff120f2e704abe4be8ce31a43c0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=644df69c08e6c5b832b7b34b54a7e616efc276686ea257ca570c7b0af25e03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d9e492b73ab5e7b411ca38a73ec25f1334931010f25867aa8dd2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466faed543a83225ae87e5f4fa930e2a1af4d46cb19721cc97cddd9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58d034db684b5b9548fa8a2596d5ef48bdc0827f3c936757f824f25190410c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5987d3cbe26bcf75946a86d0555108608e7ed18325dd60fe7d4fd200ee741d + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548b78fe393615d3918bb584c160d00bae8672e05bb010987c999f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466273122b0e5f91c8b4a7e9e8a59e9c89269df77d30fbeaec514c2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7474619bc60a98042cc7bce09f4f631f20af421de18fc434457e2fb7f9e48e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=00783db976d144d85fb4dbb341e908748eb0bc90123fcf4162b10cd34277ef + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d738849e4f8635b57bf9f7c2d1cce4db786552b21fc809e097b9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466874006ee8e970d1140a8eee4c4694467251fe8db35416cf00ff2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d65a6ebbe3f38a2f2de8529b5203ed2668cbcefc48219fce3f2414bf3b2bdb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cdef5b6bd32cdca6ebfe2a3b697caadc3099b9e820eb1c9d27d28b6ed99138 + +handshake=Noise_NK_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bb9e8fd1c92e99737291c111956e17ab +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d97cd906e611b305ce4c22ffd315b750 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9cfd3ddea89d9f445475098f834e572ec4a8c5e9be740dd92831ef6cf6fd9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5db2eb7c7b37b33cd42fd321e05d9048c9be3efa0ae3a8c76724307e7562ff + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254718a7d4c2e3c99dbf622a533aee2274f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c286f86f4a7cfd2b81fe3d1444add3f2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01d0ab0f394923f44c3abad69154757bbf902c64c5219bf8c624d69b11c959 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c2a431db9e64c43b6c0a520547bdd8e1368358c099345ab4969f1bb4a9299 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254afc9110414941f0b3fa72bd395095718 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669c069692405e7802986d04a3d2430961 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d7766291245b52e9d504ca48bc3fb1118bdf46179c1b9bd32c925493533b3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11a8d0014a1f8b258deb81bed19ea97bec009031d6a7a374eba5528490926c + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f93a440c4497c8dc01d655826bc1e042 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846680f0334cb21d5a78f12947bb80c7735b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6647abf5c995fb4b851bfd63c8e699286071c1fc2559764335c6329e2bea0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89e20c2dca7e4c2202aa731271c5d2081164c86e7b365ca98465961e7113a6 + +handshake=Noise_NK_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e44c6b6a0a9a28f5daf1796ae55886ff960a634ddc73b72e7b0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666e1a02e46e9053fa2a81f648b1fee43c438299bba0e77bc34d08 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9cfd3ddea89d9f445475098f834e572ec4a8c5e9be740dd92831ef6cf6fd9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5db2eb7c7b37b33cd42fd321e05d9048c9be3efa0ae3a8c76724307e7562ff + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ca3238dddb5256cd690a81f68c59b5d5216a7806cc1e63fcdceb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660aa92dceb01712153f8dbce8ba3752e32b0a055a3f56a4900e58 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01d0ab0f394923f44c3abad69154757bbf902c64c5219bf8c624d69b11c959 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c2a431db9e64c43b6c0a520547bdd8e1368358c099345ab4969f1bb4a9299 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b74e16d251935c4ba865774bfc2d3703bf09fe397d41b70e66b0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466668442074729cbc1afdd21edaed1bd0c2bfe8b0bbd4797e22a73 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d7766291245b52e9d504ca48bc3fb1118bdf46179c1b9bd32c925493533b3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11a8d0014a1f8b258deb81bed19ea97bec009031d6a7a374eba5528490926c + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b3af61cb5aa81f19c8ece0651d022203328454673d001ede6b8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bf9e6c127466353179c7c004f953f2584b10238b823e7cc5e97c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6647abf5c995fb4b851bfd63c8e699286071c1fc2559764335c6329e2bea0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89e20c2dca7e4c2202aa731271c5d2081164c86e7b365ca98465961e7113a6 + +handshake=Noise_NK_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254660f1a4e72e678e4b0bcacd08c2cc9f4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669b3dc8f07dd44673e4833fc90ce1164e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9cfd3ddea89d9f445475098f834e572ec4a8c5e9be740dd92831ef6cf6fd9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5db2eb7c7b37b33cd42fd321e05d9048c9be3efa0ae3a8c76724307e7562ff + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625460387695ddb6a97647f93847e8923922 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dd59aa9c3ee7803c98e3651db6b3e81b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01d0ab0f394923f44c3abad69154757bbf902c64c5219bf8c624d69b11c959 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c2a431db9e64c43b6c0a520547bdd8e1368358c099345ab4969f1bb4a9299 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544259ae3d24d8665ff7ce9256b701954c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c3d5626dcdd6dbd0ef679f92fa2f4518 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d7766291245b52e9d504ca48bc3fb1118bdf46179c1b9bd32c925493533b3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11a8d0014a1f8b258deb81bed19ea97bec009031d6a7a374eba5528490926c + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9cfbfa816d97f7a4c47a7a9f8ecc6ac +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661629749d9a9c1558d3a8027a81a7b97f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6647abf5c995fb4b851bfd63c8e699286071c1fc2559764335c6329e2bea0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89e20c2dca7e4c2202aa731271c5d2081164c86e7b365ca98465961e7113a6 + +handshake=Noise_NK_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e44c6b6a0a9a28f5dafb35dfe4f2cf52995fadd57f0a4006d1c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666e1a02e46e9053fa2a81414fd4a5bd34dbd73cb3a6e1b896bce6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9cfd3ddea89d9f445475098f834e572ec4a8c5e9be740dd92831ef6cf6fd9e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5db2eb7c7b37b33cd42fd321e05d9048c9be3efa0ae3a8c76724307e7562ff + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ca3238dddb5256cd690ae943692a4c055f22d3dd834ea90edfd8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660aa92dceb01712153f8d214f8f71c03c898cbd891e751f10d132 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01d0ab0f394923f44c3abad69154757bbf902c64c5219bf8c624d69b11c959 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c2a431db9e64c43b6c0a520547bdd8e1368358c099345ab4969f1bb4a9299 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b74e16d251935c4ba86516dfd74e045ff1c291281bcaa9362d00 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466668442074729cbc1afddf5f76f8ec753aa54926873c9096709c3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7d7766291245b52e9d504ca48bc3fb1118bdf46179c1b9bd32c925493533b3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=11a8d0014a1f8b258deb81bed19ea97bec009031d6a7a374eba5528490926c + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b3af61cb5aa81f19c8e33d34af062c6a72f793a6612ed12887f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bf9e6c127466353179c7c97611f0c4ac0ac3142512e76f650851 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6647abf5c995fb4b851bfd63c8e699286071c1fc2559764335c6329e2bea0f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=89e20c2dca7e4c2202aa731271c5d2081164c86e7b365ca98465961e7113a6 + +handshake=Noise_KK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254de3641cda8802b636ee7afe370f7e34e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e4c15cda24dee01c5c60ef6c4d6b92b3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab44bf778165ad086eaebbb994df826628b3fe26ad310642480a1b2af8fc23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=baacf816b83aaeb15954621113f8e0603cb79168fe6308b87413004beee4d2 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625498bf0afa6ad430bef2179595b80f00af +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660bc0a013b37277dafd0e2a2073ac3cc0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe6f6f749a1495883a1715674543c2ebe56c1cb674d4f4e47f9086553700ce +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7a88c03c458db5b49827d899535210ba453d7dfc0f76a661b8cad08cf967ef + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625482f300522a0b96d0e03c3d41f98f6030 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846652279732a99893f3b89cf55f3784a3b5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=de7af56efebaae1c6a616b624b39a441d8b82e09a2f2a30531a7c30441e6eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=408aae72aaa26f98d436f4a64c34ea26baa1802548774b8f14cff3d1891895 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f76e9ef85e5bc141f0d2ac73c491af69 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466479ea79a1a541cbc7eb522078716e1d4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cdafd1b6afea01667934ed26de85e3a200927343f534ccee0bdab0fbbe5aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c4b0bdb11291ee7b67616af3c37e7a9f8c400c715e7f9142a620db4fd3e05 + +handshake=Noise_KK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254558809aaeff03abdf354a87685ef23c3191ad86ae0c81bbaafa8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f7c3b2f7cef28a2f21245150a4abd05d6404ab474c115c578ea5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab44bf778165ad086eaebbb994df826628b3fe26ad310642480a1b2af8fc23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=baacf816b83aaeb15954621113f8e0603cb79168fe6308b87413004beee4d2 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b999c716e2b5ebd7dddc18c68985cfb4351b19d5aa51e6b6a3d9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ad07cf9d7d4c88039123d1fae114ca14da9754cad2103495e943 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe6f6f749a1495883a1715674543c2ebe56c1cb674d4f4e47f9086553700ce +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7a88c03c458db5b49827d899535210ba453d7dfc0f76a661b8cad08cf967ef + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541a96b079a0d93c9c8a155898e5985630a9b1f023773114dabe32 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466677a31f9e25c3322951402efef0b854d68e456565be88e0d51a2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=de7af56efebaae1c6a616b624b39a441d8b82e09a2f2a30531a7c30441e6eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=408aae72aaa26f98d436f4a64c34ea26baa1802548774b8f14cff3d1891895 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d75d4599f7a207000b95e3ba21772976160bc0d0e9d849b969b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669ba2c1c12e0ae525b5442707aa5ea703c57d8aa875aa18ed909a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cdafd1b6afea01667934ed26de85e3a200927343f534ccee0bdab0fbbe5aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c4b0bdb11291ee7b67616af3c37e7a9f8c400c715e7f9142a620db4fd3e05 + +handshake=Noise_KK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c2b1750e0c698c0a6112819f9c76fc36 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846680da3b11f10f1a9b7790d0edd4dffbaf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab44bf778165ad086eaebbb994df826628b3fe26ad310642480a1b2af8fc23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=baacf816b83aaeb15954621113f8e0603cb79168fe6308b87413004beee4d2 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543dbdbd15ce16ebbd5cbe94c31693a31d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c6530671018ea8a0fc755a25fc2567ce +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe6f6f749a1495883a1715674543c2ebe56c1cb674d4f4e47f9086553700ce +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7a88c03c458db5b49827d899535210ba453d7dfc0f76a661b8cad08cf967ef + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254840a997d6af2ba012dd07b2df7798fee +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ca8bb47ff4a43848304c6d2edcf068dd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=de7af56efebaae1c6a616b624b39a441d8b82e09a2f2a30531a7c30441e6eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=408aae72aaa26f98d436f4a64c34ea26baa1802548774b8f14cff3d1891895 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625482752d661cd7555efeb06de81c9c7440 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466faf6abfeb8c57688af793a94b8b59903 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cdafd1b6afea01667934ed26de85e3a200927343f534ccee0bdab0fbbe5aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c4b0bdb11291ee7b67616af3c37e7a9f8c400c715e7f9142a620db4fd3e05 + +handshake=Noise_KK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254558809aaeff03abdf354ad47d26523f1b98b5ce386c3b066ff53 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f7c3b2f7cef28a2f212487967f4b709e22ff452dcb68821a10aa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab44bf778165ad086eaebbb994df826628b3fe26ad310642480a1b2af8fc23 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=baacf816b83aaeb15954621113f8e0603cb79168fe6308b87413004beee4d2 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b999c716e2b5ebd7dddc071a74c7c4c9cb80ac268b23a5284fc2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ad07cf9d7d4c88039123b962375716b252dc4ad12cfe6f5d4bb8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe6f6f749a1495883a1715674543c2ebe56c1cb674d4f4e47f9086553700ce +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7a88c03c458db5b49827d899535210ba453d7dfc0f76a661b8cad08cf967ef + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541a96b079a0d93c9c8a154abc656a5b149ecbeb06e87583b65868 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466677a31f9e25c33229514bb8c7076d4faff8789a0e351738b86fd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=de7af56efebaae1c6a616b624b39a441d8b82e09a2f2a30531a7c30441e6eb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=408aae72aaa26f98d436f4a64c34ea26baa1802548774b8f14cff3d1891895 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543d75d4599f7a207000b9c74a6e5fb64546dabaea326eae41e103 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669ba2c1c12e0ae525b54442c957df906bb8905ee7620374ebf0b2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cdafd1b6afea01667934ed26de85e3a200927343f534ccee0bdab0fbbe5aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2c4b0bdb11291ee7b67616af3c37e7a9f8c400c715e7f9142a620db4fd3e05 + +handshake=Noise_NX_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846686b5f4e8c51a605bcb276206a6df60ae938b905adaf29a2dae4a4951bbd9ac64830ab64f2329646560b930979ff52da8dda7c0677c502dba13c078b5afd1bf11 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92613cda6ccb2936449efb8ff870b5a4536f5734a4e31056d38101230762e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed89355072429afe6c3442ba7af66f6647499291bab58d40f6a392e79ff80a + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a9ee73b4288fdbc31cb51797c65fbaa9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664f6b8c9a95aeb764b26cf8c501bacc34e529749e4f6ae88920bd387fabb8637dcde2392baf3709659849325856ac9cf356aaefe992efcb4f9ab2a3970fbb99f5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=48a1263c75d2406120b1a37c67ea6dbfd419846d447bb9561f7b2e59e519fb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=73b72d691daf65626d78168e0ed56bea89856f26a9dafe3e9bfc9eb6e0f31d + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254630415173b9f1928701ff2289f37d561 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846605a586d5481fff45caeea1cd0655af37781458d66a4815875d47b78c96a3a12d093a0dc166d20f0c3214a4626b9e66336caf89021d364d65e4772bc8f1321040 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0939720a26cecdc36b1c4026bd90b3dbcf385f01e559ca5a0a0d3e873490e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d4d6c20c1864598f66f01fe45acc18f5bda9ffa8df1ef6ceb816767b89a58 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254162c9c2f5940535c6bfd1f890e60408d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466353ad209b6a362c223414b1d0a03e9e81e22fa4caeb6b362260fbfe5c128631598e58eba6e707e7d2222949ee232b54ebf61e33970b46cd4eeac807a2f0cf192 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a4e0c92d865ded40ef3c75ba54bdf98e66a5a0f2518d3b0a7f6f0282f2b20a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=295ed0f56eb5f31822f8d9555d259cad3287f00b0a190e11039c84931c3da5 + +handshake=Noise_NX_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846686b5f4e8c51a605bcb276206a6df60ae938b905adaf29a2dae4a4951bbd9ac64ab58309bc12c2c6833badcfdd3d7ff0761dbe60d6d29ade8507d29fb2bc4117057fc8179e6fbef5007ad +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92613cda6ccb2936449efb8ff870b5a4536f5734a4e31056d38101230762e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed89355072429afe6c3442ba7af66f6647499291bab58d40f6a392e79ff80a + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e9015cba2a23b0096a05011567485f6bf02291236c1a148210fc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664f6b8c9a95aeb764b26cf8c501bacc34e529749e4f6ae88920bd387fabb8637dd40f5cfab465b3b2502a36bd5eb32fcfcd18d09a129a297e8b6ec14c40f49ddefba21635f51fb72aa086 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=48a1263c75d2406120b1a37c67ea6dbfd419846d447bb9561f7b2e59e519fb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=73b72d691daf65626d78168e0ed56bea89856f26a9dafe3e9bfc9eb6e0f31d + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546f39612d4d40b9e9cfdc3a11c3356eeff3ebf41fbfaeeef9aa39 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846605a586d5481fff45caeea1cd0655af37781458d66a4815875d47b78c96a3a12d555e64b1d866a2cc146e4d71d56b0bacf2c3abdcf587228060f0a41bb179568b9c95191f7bdb9ab94e9d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0939720a26cecdc36b1c4026bd90b3dbcf385f01e559ca5a0a0d3e873490e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d4d6c20c1864598f66f01fe45acc18f5bda9ffa8df1ef6ceb816767b89a58 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625438e8bbb2574005b8a72c7fc4a5455835244356622ed2cdbbd68d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466353ad209b6a362c223414b1d0a03e9e81e22fa4caeb6b362260fbfe5c1286315de9dafc57e6d45a3fbd49aced15f14ce967be96d154f36efe24015a68924e69b7c9135349ce6264f6c59 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a4e0c92d865ded40ef3c75ba54bdf98e66a5a0f2518d3b0a7f6f0282f2b20a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=295ed0f56eb5f31822f8d9555d259cad3287f00b0a190e11039c84931c3da5 + +handshake=Noise_NX_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846686b5f4e8c51a605bcb276206a6df60ae938b905adaf29a2dae4a4951bbd9ac64609b51f99bea30ec0bbedbd1007843d83c9763a959b00ab5cab5ba49eafb3e2e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92613cda6ccb2936449efb8ff870b5a4536f5734a4e31056d38101230762e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed89355072429afe6c3442ba7af66f6647499291bab58d40f6a392e79ff80a + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d93a8a6ccad06b8a39521b804712e760 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664f6b8c9a95aeb764b26cf8c501bacc34e529749e4f6ae88920bd387fabb8637d74d1f7e7e208bab05d20d4b685ce7dbd7c3ac274d2fc417b9ea17fca299290ea +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=48a1263c75d2406120b1a37c67ea6dbfd419846d447bb9561f7b2e59e519fb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=73b72d691daf65626d78168e0ed56bea89856f26a9dafe3e9bfc9eb6e0f31d + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254921fe5c4bb90760e53d6faf1a0740c79 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846605a586d5481fff45caeea1cd0655af37781458d66a4815875d47b78c96a3a12d92c26414634b717744bf686cda3a086e2a5f112e7b50193a0981c9052b26b95a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0939720a26cecdc36b1c4026bd90b3dbcf385f01e559ca5a0a0d3e873490e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d4d6c20c1864598f66f01fe45acc18f5bda9ffa8df1ef6ceb816767b89a58 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a816c865955730f32f7955893a0d7f2e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466353ad209b6a362c223414b1d0a03e9e81e22fa4caeb6b362260fbfe5c128631555051ef062c98db54b470d1e15b0050171b4b5a3b57703c66b018918176481dd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a4e0c92d865ded40ef3c75ba54bdf98e66a5a0f2518d3b0a7f6f0282f2b20a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=295ed0f56eb5f31822f8d9555d259cad3287f00b0a190e11039c84931c3da5 + +handshake=Noise_NX_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846686b5f4e8c51a605bcb276206a6df60ae938b905adaf29a2dae4a4951bbd9ac640fc955b72cd7be36df1431bc363bf15b61dbe60d6d29ade8507d549c2b17ff58629ba542d5129adf100f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=92613cda6ccb2936449efb8ff870b5a4536f5734a4e31056d38101230762e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ed89355072429afe6c3442ba7af66f6647499291bab58d40f6a392e79ff80a + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e9015cba2a23b0096a053a030712430d2c4b67068f03021e228f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664f6b8c9a95aeb764b26cf8c501bacc34e529749e4f6ae88920bd387fabb8637da2ba3faccfe2faa68a3139e1c8447a55cd18d09a129a297e8b6eae2479c85097b112227d3a5f8c151535 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=48a1263c75d2406120b1a37c67ea6dbfd419846d447bb9561f7b2e59e519fb +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=73b72d691daf65626d78168e0ed56bea89856f26a9dafe3e9bfc9eb6e0f31d + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546f39612d4d40b9e9cfdc571de866bca651aafdc036069e6287ee +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846605a586d5481fff45caeea1cd0655af37781458d66a4815875d47b78c96a3a12d10417dc13d71a4453495b69c0892beb5f2c3abdcf587228060f0258e113345473d901ace83f9bdbd0b41 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0939720a26cecdc36b1c4026bd90b3dbcf385f01e559ca5a0a0d3e873490e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d4d6c20c1864598f66f01fe45acc18f5bda9ffa8df1ef6ceb816767b89a58 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625438e8bbb2574005b8a72cea9f0f940e1159de27b869b82e9779f0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466353ad209b6a362c223414b1d0a03e9e81e22fa4caeb6b362260fbfe5c1286315e1f3a591d5886270af814b41d8bacb7a967be96d154f36efe240b4f5bbe437a4669d354ec3f988467b16 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a4e0c92d865ded40ef3c75ba54bdf98e66a5a0f2518d3b0a7f6f0282f2b20a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=295ed0f56eb5f31822f8d9555d259cad3287f00b0a190e11039c84931c3da5 + +handshake=Noise_KX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622be88163c561546e4bed5f7edf59c4a66de1b08618f33e5795acaac602ccefed747d2332f470a6322d692464a05fcd67cba64be6a7e2398b84f0874a7d27c38 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0bdd14922642db2bd89e286bac9a93db23f5677f0c21a2504d12a30ba345c9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01d6ba6fa72b364f3595ecd4fcfd2163c6419dcaaf81400f2a2475841bf0d8 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d46828feccb106fce1347259efe3d560 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e10980f3530a4aaf3535bcd0434d86038c899f9f7eaa14ec3b953dfccd14f38eeceda506dac5ffaa99ff52fe7504945eb9b6072986d1e7120e06d3c1972f7180 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=10541bac3d4a63122a37a4f7b5dcfcc525e1181fc5dd8acc49d47583d318a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=863dcf756c35668a469a0b54d4e1dfe6c8eb5731fefa8fd1ea01ee193ca65a + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254239128e9c724ebca8616533a70d2437b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666502920f436afe0924fb9e2089dae0157d3aece8be75d5e40c6c32324963763a5208664eb984e338151d464d04f944b15fc0cf85a10bb0c55d8971abe75aa2b3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4df46901c83ffc83cb5a2b8e3f551f94413e760c545fe690c376fcc67d2c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6ae230f4066266b0d5acbd1f88e9a369008a22f37234bb29edccccd574835b + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254016d9bce67aca6fbde6cd635a26a793b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665707e22c0421b4143fb60cdb66d4abe8e9f9f96622ed7415a4bef49e881e6259ec92755a87cf9ae7807a98d2b99b2886a6afd2cf42f6ec465d945fceeaa6ca42 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccf1e63eb05b5935b3925d91e55cc46e95c883af0c86ceb81b44679d63b8df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bfb507e53620a99a87de6c5118a296da629e71582b4315d3f9d276cd6d8123 + +handshake=Noise_KX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622be88163c561546e4bed5f7edf59c4a66de1b08618f33e5795acaac602ccefea1671c0794e5e89f47225379b721d4ec0bff04812072f6475715344dbbf02f94c684290d67dbdbc8207d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0bdd14922642db2bd89e286bac9a93db23f5677f0c21a2504d12a30ba345c9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01d6ba6fa72b364f3595ecd4fcfd2163c6419dcaaf81400f2a2475841bf0d8 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3e81f3136465c96cebd9ede3119a58997cc9451cb028c655ffe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e10980f3530a4aaf3535bcd0434d86038c899f9f7eaa14ec3b953dfccd14f38e945d19af90678c770e7fa5b44cf2f028a97d8dcafbf2716d9afdcfbbcb54a91f9a244f39bdc24b915afe +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=10541bac3d4a63122a37a4f7b5dcfcc525e1181fc5dd8acc49d47583d318a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=863dcf756c35668a469a0b54d4e1dfe6c8eb5731fefa8fd1ea01ee193ca65a + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254326b26fa793456510d57c3fbdb793f6b4b818a362b84c1b66c8f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666502920f436afe0924fb9e2089dae0157d3aece8be75d5e40c6c32324963763a4a342ec239c8c23d581a3c32e692458a71115f8a46511990d9df9e566c592c7cd453946d482d1b0471ca +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4df46901c83ffc83cb5a2b8e3f551f94413e760c545fe690c376fcc67d2c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6ae230f4066266b0d5acbd1f88e9a369008a22f37234bb29edccccd574835b + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548ae113e0354a922eba4fcd8f1779c9e2a7e299b5dd36d51a3a88 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665707e22c0421b4143fb60cdb66d4abe8e9f9f96622ed7415a4bef49e881e62592ad072445cec53458b1a2afe797bd4b04144407359790a257fcb9ab38935582670d3355072c7f3df624b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccf1e63eb05b5935b3925d91e55cc46e95c883af0c86ceb81b44679d63b8df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bfb507e53620a99a87de6c5118a296da629e71582b4315d3f9d276cd6d8123 + +handshake=Noise_KX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622be88163c561546e4bed5f7edf59c4a66de1b08618f33e5795acaac602ccefe8ac78598314baf570622d86009c726c36d35cf3d7a7d73b97b17feb38c3b39d8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0bdd14922642db2bd89e286bac9a93db23f5677f0c21a2504d12a30ba345c9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01d6ba6fa72b364f3595ecd4fcfd2163c6419dcaaf81400f2a2475841bf0d8 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254af3f8d444ba03713f5022a823e640a91 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e10980f3530a4aaf3535bcd0434d86038c899f9f7eaa14ec3b953dfccd14f38e10d88a49863b30c39deeac932734a107a7dcd046a5c72e44ffe7568799d921d8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=10541bac3d4a63122a37a4f7b5dcfcc525e1181fc5dd8acc49d47583d318a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=863dcf756c35668a469a0b54d4e1dfe6c8eb5731fefa8fd1ea01ee193ca65a + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625400e84c01aaed5f725ab7f61e29eeb91b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666502920f436afe0924fb9e2089dae0157d3aece8be75d5e40c6c32324963763a9c046b9524fcbdb33f1659ae34847bf2b199c8870b646a54304818f51af06071 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4df46901c83ffc83cb5a2b8e3f551f94413e760c545fe690c376fcc67d2c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6ae230f4066266b0d5acbd1f88e9a369008a22f37234bb29edccccd574835b + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e705ff1f11873ffc5d577a6a5cf567e0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665707e22c0421b4143fb60cdb66d4abe8e9f9f96622ed7415a4bef49e881e62597f5a32f7d06d14b6f025a25d9c5c4d4757d58ed15d8db3099ad8e3eb486f924c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccf1e63eb05b5935b3925d91e55cc46e95c883af0c86ceb81b44679d63b8df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bfb507e53620a99a87de6c5118a296da629e71582b4315d3f9d276cd6d8123 + +handshake=Noise_KX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622be88163c561546e4bed5f7edf59c4a66de1b08618f33e5795acaac602ccefee3df782d6947d1c911aac6358c29ee3a0bff04812072f6475715256b60c70ed7efb0e39e3228d109cc28 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0bdd14922642db2bd89e286bac9a93db23f5677f0c21a2504d12a30ba345c9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=01d6ba6fa72b364f3595ecd4fcfd2163c6419dcaaf81400f2a2475841bf0d8 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3e81f3136465c96cebdfe53333e37d04b3ecfc1ce18c24d8655 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e10980f3530a4aaf3535bcd0434d86038c899f9f7eaa14ec3b953dfccd14f38e0d9282cf7902b2cf30bdc567ba9b58c2a97d8dcafbf2716d9afd88d956892efd1b1f7e4e9e43e5d33812 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=10541bac3d4a63122a37a4f7b5dcfcc525e1181fc5dd8acc49d47583d318a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=863dcf756c35668a469a0b54d4e1dfe6c8eb5731fefa8fd1ea01ee193ca65a + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254326b26fa793456510d5783814b7b0b910fa84f2e03549260a3ff +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666502920f436afe0924fb9e2089dae0157d3aece8be75d5e40c6c32324963763a9e52ca3691a9bb4da162c6b52f63a33d71115f8a46511990d9dfae8beae37024a6d8f9d64a13ed725a88 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4df46901c83ffc83cb5a2b8e3f551f94413e760c545fe690c376fcc67d2c6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6ae230f4066266b0d5acbd1f88e9a369008a22f37234bb29edccccd574835b + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548ae113e0354a922eba4f54c106d22ef8b5012baa9d3f6282043e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665707e22c0421b4143fb60cdb66d4abe8e9f9f96622ed7415a4bef49e881e62598c2243a2c57862be374df2bcf1dca08b4144407359790a257fcb737585008b71d92634ed2e0006947bf3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ccf1e63eb05b5935b3925d91e55cc46e95c883af0c86ceb81b44679d63b8df +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bfb507e53620a99a87de6c5118a296da629e71582b4315d3f9d276cd6d8123 + +handshake=Noise_XN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466421a842962910af6f41bae34e0432825 +msg_2_payload= +msg_2_ciphertext=90ec9aa1d942e2a4659f38aa2c3aaea30db7c881779be22b7a75216bfc85f5b9a89cc47f2214dfe6ef4dbfcde419e1b976d89bde05869c2d4f63411b62d9e1aa +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a3a03ed5f7e2e7f28a52c981ec059601e1f159914f3f3cd9a2c6c4430dd720 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=014e0d10df4f445f70e49bd6c70f73559fb941fd476c2a024a3c41faa85fd5 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d18427cf1cf5b8d6efedc50e72f98d61 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a868b8ef62dddac660ccbd0ef5a2f638 +msg_2_payload= +msg_2_ciphertext=711758abed5d3a6ac8da8b44e5c5e8172fc2ac0d276c26869df19a6d7692bc215109dd8465dccae346b7c3244b8dec4bb0b920dd013a869726939ae290787a03 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e70cfd7879dcb0954e022417341a5610ffa95efe16d46fd0a009ec563ead28 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a3cf3d1c5147d0674557713d2bb5cee2dd14b19fb068191ccbae7f2eb37d15 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254adaac346cc6dc2d8445919ef7814b47e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dc9fdacd87762acf1ffc1fc0030efbdf +msg_2_payload= +msg_2_ciphertext=ed69ae5a01433c142b45a612ad047ea28ea5fb892aec8502d2301d25379af0062277dc4aa770beb5920c299388f21f64076253ef99811b89c4c4d095baa9b663 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0466462e068b7a45a52f923a3ff92045c003d75c0abfb5fef22e50930cdf0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1e2d80773770ecd305c15a6eb937794aacc757668d6a35c0b6b757c3661d9 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541a0f3449ec3aefd8d282186f3cbf6d2c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c6de47296cd1a124ae1bede32568b2eb +msg_2_payload= +msg_2_ciphertext=8c4f737e9523fc333fd7790a0da924aa5e9102815e6e58470ebfcb225505442f17316a2cfa8a0e08d6e8c61612390b023ead1a6e918977666182bf060f6e1f32 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=36b805eb8ae644d22dcd34bded50eb1d9ef8492011dfa55686877643444bf7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a623e85f1faa8a611b90e0267b9849cd137835c068773781c6020f6c29760e + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547b1edc47b836d1657bba9ae2905187f9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665288e35fd769417d86673fe39856df48 +msg_2_payload= +msg_2_ciphertext=f9de295774dd85031fbfc643d31a9b8d22ad1c59c8c692f8fc24131ca25245d54aaa337b7f7543c27e2e7cece2034a3db47e10ce55ddb3e0500fc0707275b6a2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=94d5355cbc643ba0617f5cb48d4dbc0bdd474526acea6a03788ffd875ed37c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d1ad326bfcc585060bd2b228a417401e532ebc5379b65d120a4c490131b02a + +handshake=Noise_XN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466922d0c0809fbcd211f3ea7a49bd48d7d21b00709e8be9a1224e8 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=90ec9aa1d942e2a4659f38aa2c3aaea30db7c881779be22b7a75216bfc85f5b9ef116e53e5dd64ea8edb4fe0b9f020503103e387380039fd95ec75f82879c19b87bc1551964b8f019c8a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a3a03ed5f7e2e7f28a52c981ec059601e1f159914f3f3cd9a2c6c4430dd720 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=014e0d10df4f445f70e49bd6c70f73559fb941fd476c2a024a3c41faa85fd5 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c40f70b1887c5e34173b42f5026cd011744f344d83d07fef6cb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622f0479024f9448013d11ed7cb13158b680cbd558e5f3ddd79c3 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=711758abed5d3a6ac8da8b44e5c5e8172fc2ac0d276c26869df19a6d7692bc21b951c8a293b10a8f53d3df938218ba8f669a67d1173c5f07ed10faebb25bf8d08eb5cf41230028d4f802 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e70cfd7879dcb0954e022417341a5610ffa95efe16d46fd0a009ec563ead28 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a3cf3d1c5147d0674557713d2bb5cee2dd14b19fb068191ccbae7f2eb37d15 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254379bde1d982cb2c03b9125fd7ec573360c0d9eec0f0edc62514e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846647abc11d0a30e8f48bee07a92bcc55f96d90613992ed2d1134d8 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=ed69ae5a01433c142b45a612ad047ea28ea5fb892aec8502d2301d25379af00620ccb49ae6217d2b906749a1d0901aa8245792e450b5a4856e2163b939b2113c20dcc1f6f962a4553e9e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0466462e068b7a45a52f923a3ff92045c003d75c0abfb5fef22e50930cdf0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1e2d80773770ecd305c15a6eb937794aacc757668d6a35c0b6b757c3661d9 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ab4c7101ed3993f615d370a8828e83d1b95e936d6543b31cf738 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0aa4588158d1d69aacd89d72b0212efd61f553f5b46dced9288 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8c4f737e9523fc333fd7790a0da924aa5e9102815e6e58470ebfcb225505442fcb02ed71bba2e642e3c673513f3086f2eabc32362bb438fa2719088bbc8b17eb0ab94995f4ef2b2e8240 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=36b805eb8ae644d22dcd34bded50eb1d9ef8492011dfa55686877643444bf7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a623e85f1faa8a611b90e0267b9849cd137835c068773781c6020f6c29760e + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f9c15e88f3b35e1fb6ee32fc27e793d457328549cf440cf21bc8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dccf8bea81d7143217517e7f8889214aa825fde0c0f5f3730b04 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f9de295774dd85031fbfc643d31a9b8d22ad1c59c8c692f8fc24131ca25245d511898ead584b2dff13d737c764a1068c5d79d90ea348d9a29e201390c72628151e1ec8ae3064c1847ff8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=94d5355cbc643ba0617f5cb48d4dbc0bdd474526acea6a03788ffd875ed37c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d1ad326bfcc585060bd2b228a417401e532ebc5379b65d120a4c490131b02a + +handshake=Noise_XN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466afdc554dbb2a7201c412bb437be1c270 +msg_2_payload= +msg_2_ciphertext=90ec9aa1d942e2a4659f38aa2c3aaea30db7c881779be22b7a75216bfc85f5b9ea8fcff35f027e4a4d34061afc8f293f1cc2d2845ad0e6c60fb28cd6a97ee7c9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a3a03ed5f7e2e7f28a52c981ec059601e1f159914f3f3cd9a2c6c4430dd720 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=014e0d10df4f445f70e49bd6c70f73559fb941fd476c2a024a3c41faa85fd5 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547efeb1446d33829e9121e2dd88d5890e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663a379fc907edb2d482c7cfd079c9061e +msg_2_payload= +msg_2_ciphertext=711758abed5d3a6ac8da8b44e5c5e8172fc2ac0d276c26869df19a6d7692bc21b2dbb6994af1e68351ca08a13d7aaacc314eb77d44983a1b8c0e73c6452cdbdd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e70cfd7879dcb0954e022417341a5610ffa95efe16d46fd0a009ec563ead28 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a3cf3d1c5147d0674557713d2bb5cee2dd14b19fb068191ccbae7f2eb37d15 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625482b27dc5a03ff90f7101dc91e98e48d5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6c92addd63257386faff8abe78e38b0 +msg_2_payload= +msg_2_ciphertext=ed69ae5a01433c142b45a612ad047ea28ea5fb892aec8502d2301d25379af006b1f0245bcfdf0581add0bd95d520f601f53d08bc3407f230a562a42d9ffda18e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0466462e068b7a45a52f923a3ff92045c003d75c0abfb5fef22e50930cdf0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1e2d80773770ecd305c15a6eb937794aacc757668d6a35c0b6b757c3661d9 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625417f654a5baf18317e0cbe73b91ab38e4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846655bb48ca5581a0f31d217afbb880f4b2 +msg_2_payload= +msg_2_ciphertext=8c4f737e9523fc333fd7790a0da924aa5e9102815e6e58470ebfcb225505442fe7f943ccead5ea1eddbdafc92b73898d7b606fcfd0aef45e783d25f42f380a71 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=36b805eb8ae644d22dcd34bded50eb1d9ef8492011dfa55686877643444bf7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a623e85f1faa8a611b90e0267b9849cd137835c068773781c6020f6c29760e + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254edefc841a615045a125f9dca19e4587b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846640df4f3bd14e278b1fe26af20aec9e2d +msg_2_payload= +msg_2_ciphertext=f9de295774dd85031fbfc643d31a9b8d22ad1c59c8c692f8fc24131ca25245d55076475f2e0d77cf754774a9f1fbc7fc540731fe9a5acfbee5ec79b48fb9cef3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=94d5355cbc643ba0617f5cb48d4dbc0bdd474526acea6a03788ffd875ed37c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d1ad326bfcc585060bd2b228a417401e532ebc5379b65d120a4c490131b02a + +handshake=Noise_XN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466922d0c0809fbcd211f3e38dde4eba0b653d54097896cd7d5dbd0 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=90ec9aa1d942e2a4659f38aa2c3aaea30db7c881779be22b7a75216bfc85f5b90c44c7fe245a16301dd8dc8addcc5ca23103e387380039fd95ecb996d7be061eb5ff1fc53559cd9e193d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a3a03ed5f7e2e7f28a52c981ec059601e1f159914f3f3cd9a2c6c4430dd720 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=014e0d10df4f445f70e49bd6c70f73559fb941fd476c2a024a3c41faa85fd5 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c40f70b1887c5e3417316dcb4d39a81bfcdc6d54853afdc3136 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622f0479024f9448013d1c4dd5c46e912265bc7f262f8f9b87d4d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=711758abed5d3a6ac8da8b44e5c5e8172fc2ac0d276c26869df19a6d7692bc2143d3856c18125b39f327923b49af097a669a67d1173c5f07ed10aa46ec9fbe18ede3cfb2e7f69d677010 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e70cfd7879dcb0954e022417341a5610ffa95efe16d46fd0a009ec563ead28 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a3cf3d1c5147d0674557713d2bb5cee2dd14b19fb068191ccbae7f2eb37d15 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254379bde1d982cb2c03b91964cd0759fe82fed89182aeee56f18e6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846647abc11d0a30e8f48bee4cdda0ba985e7d4b29a633657c339893 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=ed69ae5a01433c142b45a612ad047ea28ea5fb892aec8502d2301d25379af0068a312038d318ec92ac5eb587e9d8f84c245792e450b5a4856e219aa62777c215570307456d87365a897c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0466462e068b7a45a52f923a3ff92045c003d75c0abfb5fef22e50930cdf0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1e2d80773770ecd305c15a6eb937794aacc757668d6a35c0b6b757c3661d9 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ab4c7101ed3993f615d302da475cd0a6b0e5c40bf650a8570877 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0aa4588158d1d69aacd8a86346e8a06ae02b5364f1564f3c056 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8c4f737e9523fc333fd7790a0da924aa5e9102815e6e58470ebfcb225505442f6da9381647d31eb43af101b61460abefeabc32362bb438fa2719426f5763a62850870e17dabdd9d6efa5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=36b805eb8ae644d22dcd34bded50eb1d9ef8492011dfa55686877643444bf7 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a623e85f1faa8a611b90e0267b9849cd137835c068773781c6020f6c29760e + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f9c15e88f3b35e1fb6eeb3f05c99e382cdc86df79a4fa2da66c4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dccf8bea81d714321751aafc0f0c02a7ba7ee4cca458c4ddd539 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f9de295774dd85031fbfc643d31a9b8d22ad1c59c8c692f8fc24131ca25245d5c8d46971e69149e03da88ddf49bee3175d79d90ea348d9a29e20f6290a1735c098a32f1be67db24cf40b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=94d5355cbc643ba0617f5cb48d4dbc0bdd474526acea6a03788ffd875ed37c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=d1ad326bfcc585060bd2b228a417401e532ebc5379b65d120a4c490131b02a + +handshake=Noise_IN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c841939357934ea06e78f5e8e698684d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2bd30250706a1499562e15fa575c2a5fa7a3c0629af62e55b05201f5ee9a88 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8d24c99e0e9d13c7a8ea87e782a85620a2d9cfffdb51fcbfbb9f47bedb1d7a + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6392475570fd5848881a9e38debf0e3ef40f0f089c76a43dadf1559adb12f96c20d7b69e8333944ccf04538f378771335ff7c6937772e71fee4cbdd504774cc +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f612bd5240c0b09912b38443ae23b80a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8ee45a004c4c4dea075b1b53c6336c68b12499a8014ec4d159edb4d8d2d61b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c0ac2d8afe9d104aa19e725b419512b446d379380b524430ad69251033b740 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625412d935cd6b08a35c8ac9d91c82849b1318050ce5ccaeb3ff03a74fc657a862f0e9e1fcc385f2dd4e16efd6f9122f15e8d094df35f7d9fa9bbae5bb7737a4537b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d973603676b783cc27f40ddc2248b573 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ebdd5b2ca6c67d29b7d2a99fc6f852211df419b41ac7aa73b6afed124aefe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=40560f67839ab4d6af1857af31b623678ff4247bfd4fe52c298519e4b37748 + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625487f7d8fbdfe8f1b1391dda5c06ec57e068ee0de9e260a3b48444e0ec45ba243ba02332c9e0e6c9faa1c008ebffde52607c9d8d921ca2f9e8bef5846584dd0d27 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846656d415e8c837b3c9793297af04684d7d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aae275159d2a9c8f77e94377242515e9c6faa83a1479dbcb7881dbd29f0fb2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d567ed8546efc8c4efd024eb3ff7a80a2e7a3c2cb15be8d00269e7dfb0e6c + +handshake=Noise_IN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e06c1cbe16f8d6eb194e341725b655563795ebd72a92f673016a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2bd30250706a1499562e15fa575c2a5fa7a3c0629af62e55b05201f5ee9a88 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8d24c99e0e9d13c7a8ea87e782a85620a2d9cfffdb51fcbfbb9f47bedb1d7a + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6392475570fd5848881a9e38debf0e3ef40f0f089c76a43dadf1559adb12f96c20d7b69e8333944ccf04538f3787713a3f341409341bc2633a44d0d0cffc67cb924c5f817986201f89f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846697a1574e379eb22d4ed6c9bb37a249152f86f772c0b6b0405714 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8ee45a004c4c4dea075b1b53c6336c68b12499a8014ec4d159edb4d8d2d61b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c0ac2d8afe9d104aa19e725b419512b446d379380b524430ad69251033b740 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625412d935cd6b08a35c8ac9d91c82849b1318050ce5ccaeb3ff03a74fc657a862f0e9e1fcc385f2dd4e16efd6f9122f15e8dc20bd3b6d2a59bacce24fe77d836c67f156db32f914abf48a6c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466480c53c0cd421691e09cf8c71845481d77f82da21ab4404e01cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ebdd5b2ca6c67d29b7d2a99fc6f852211df419b41ac7aa73b6afed124aefe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=40560f67839ab4d6af1857af31b623678ff4247bfd4fe52c298519e4b37748 + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625487f7d8fbdfe8f1b1391dda5c06ec57e068ee0de9e260a3b48444e0ec45ba243ba02332c9e0e6c9faa1c008ebffde52601555b3462a986b29bd0d0aca61ce824686b5ee49ec4a48ca8e7f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661f6cfea732227f439b5149a4d581b9ecd78c6c61b944aad00f7b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aae275159d2a9c8f77e94377242515e9c6faa83a1479dbcb7881dbd29f0fb2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d567ed8546efc8c4efd024eb3ff7a80a2e7a3c2cb15be8d00269e7dfb0e6c + +handshake=Noise_IN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846699119bc615749ecd1e6e7d1ac6d1977c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2bd30250706a1499562e15fa575c2a5fa7a3c0629af62e55b05201f5ee9a88 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8d24c99e0e9d13c7a8ea87e782a85620a2d9cfffdb51fcbfbb9f47bedb1d7a + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6392475570fd5848881a9e38debf0e3ef40f0f089c76a43dadf1559adb12f963da30abf52e7bfc3b55a0209fcc0f7a175871e2e30e8450989365002aca269b2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662b230f643036ec899a5a4f68d9d7044e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8ee45a004c4c4dea075b1b53c6336c68b12499a8014ec4d159edb4d8d2d61b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c0ac2d8afe9d104aa19e725b419512b446d379380b524430ad69251033b740 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625412d935cd6b08a35c8ac9d91c82849b1318050ce5ccaeb3ff03a74fc657a862f07ab83b4c64b03c9e2033777cbb1312bbcdfbbe5ff2fdaf57ef374eff49d47fc6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cfc8f480e99a7c4c2ca19519a93b555e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ebdd5b2ca6c67d29b7d2a99fc6f852211df419b41ac7aa73b6afed124aefe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=40560f67839ab4d6af1857af31b623678ff4247bfd4fe52c298519e4b37748 + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625487f7d8fbdfe8f1b1391dda5c06ec57e068ee0de9e260a3b48444e0ec45ba243b5fca98a7970812685deaf53e7ffb1575eb3f3daecc6f33e17d11d5301ab96b7b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665e39de767762c2beb6d96b26e84dbac6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aae275159d2a9c8f77e94377242515e9c6faa83a1479dbcb7881dbd29f0fb2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d567ed8546efc8c4efd024eb3ff7a80a2e7a3c2cb15be8d00269e7dfb0e6c + +handshake=Noise_IN_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e06c1cbe16f8d6eb194ee5323d1b620bf0b6767e08d8027ee9e7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2bd30250706a1499562e15fa575c2a5fa7a3c0629af62e55b05201f5ee9a88 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8d24c99e0e9d13c7a8ea87e782a85620a2d9cfffdb51fcbfbb9f47bedb1d7a + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e6392475570fd5848881a9e38debf0e3ef40f0f089c76a43dadf1559adb12f963da30abf52e7bfc3b55a0209fcc0f7a1a3f341409341bc2633a483e8bf7bea8307e6dc21c16519a91cbd +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846697a1574e379eb22d4ed66f506c2ec0fe5994eea0f25cced08528 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8ee45a004c4c4dea075b1b53c6336c68b12499a8014ec4d159edb4d8d2d61b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c0ac2d8afe9d104aa19e725b419512b446d379380b524430ad69251033b740 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625412d935cd6b08a35c8ac9d91c82849b1318050ce5ccaeb3ff03a74fc657a862f07ab83b4c64b03c9e2033777cbb1312bbdc20bd3b6d2a59bacce207c6e3a1f515317eb137612cb3d35409 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466480c53c0cd421691e09cc75414f28abdc13ecc8b13cc73692825 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ebdd5b2ca6c67d29b7d2a99fc6f852211df419b41ac7aa73b6afed124aefe8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=40560f67839ab4d6af1857af31b623678ff4247bfd4fe52c298519e4b37748 + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625487f7d8fbdfe8f1b1391dda5c06ec57e068ee0de9e260a3b48444e0ec45ba243b5fca98a7970812685deaf53e7ffb15751555b3462a986b29bd0d93839bd9528630f52982f870bfd48f38 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661f6cfea732227f439b51131d5eeb7da02a5d2293f0ecd9d4183a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=aae275159d2a9c8f77e94377242515e9c6faa83a1479dbcb7881dbd29f0fb2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4d567ed8546efc8c4efd024eb3ff7a80a2e7a3c2cb15be8d00269e7dfb0e6c + +handshake=Noise_XK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549963aa4003cb0f60f51f7f8b1c0e6a9c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846630166c893dafe95f71d102a8ac640a52 +msg_2_payload= +msg_2_ciphertext=24a819b832ab7a11dd1464c2baf72f2c49e0665757911662ab11495a5fd4437e0abe01f5c07176e776e02716c4cb98a005ec4c884c4dc7500d2d9b99e9670ab3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e8b0f2fc220f7edc287a91ba45c76f6da1327405789dc61e31a649f57d6d93 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed6901a7cd973e880242b047fc86da03b498e8ed8e9838d6f3d107420dfcd9 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542bd753046e7314ec3133494e382b7a24 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b2ea43a59356b0531b01cd1572eb7dda +msg_2_payload= +msg_2_ciphertext=2d53813722d086e90ea67567c62e7363b8ac9207c580da580ef863a83ff27bcc7ad8b275fc0893de2d6b29ac0abce0a944491d09b7da32b734090a98c2c6845d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=84ae2612b7e30a08826858696ffe58b04409582f7f61a9fd89b8da7436540d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1909701a9f7ef6101bd2399cbdb58ce6a2fe375265d1b31599480046a21c40 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b29b3029f6d95e9dd623a64fdf0ffaf0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662671dcf4fe27e8fd1c025e45e28d31c1 +msg_2_payload= +msg_2_ciphertext=b9cbb82dfbae55029e5f8fde96d8295f8e132adaf171665e7e1e2ae82598eeb3cf1a6d2a1e4f9b60273187384d328fe084441b93fdfff3c58e76947db2e3293b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=66909973ba7571691166adc1cba72feaf1870d0fe1a71372421114b227bafb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a6113e6302cfedcdc0439a2606a06d1a6f0053306d188a8d0aee1a630a5e15 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542720ac573d81470b7a09238c46ff7bb7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c760c8dd0d16469689650665b8a1f189 +msg_2_payload= +msg_2_ciphertext=efe0329519660a84a2a418b869683458a06342db2cd97684000854900aa0274f5529a3d47b81a76d31e483f431b8bffd2c592e06ee566085a6cca7b48a904e74 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b9bad622368e64fbacab57ce79a664941d75ff62778de9757ca00f96ac58af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5d8a8111907d497e9905d883cfca75175f6bc39d0ae332fd3bdd6031d569cd + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e29da5e10212297d03bea07586a8960e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660a6c9b67beafadf4560b3ef5e8024902 +msg_2_payload= +msg_2_ciphertext=7e44891d25df444c83119a57b2d12d38ba30c73ae1b3894959bde4a3beddeabd73ad111c22c79bf0b7f5bf854d220e6cae35a1fa0b46e3244bedec61067b3ea0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=784797cf5ced552a14a2bce97597b2b65d3508f7aeca0bf669b54ffd1b6d71 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e5d7034b907fdced33489bb43015d216dad917aea17d4c410e24e5e6c0f24f + +handshake=Noise_XK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540c4e6c2fa1de96ff5794a3f905720f0fa07aa85019d1138cfb87 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e3186922b93e29c4a8f4d1c4e448467cbed9a9a4dd2ec38c1ab4 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=24a819b832ab7a11dd1464c2baf72f2c49e0665757911662ab11495a5fd4437e2a7ab6eac00781f1afcc98a4a72d60deed954c511b2929288a7115b740e75dd4c4eb940229b3abb9dae6 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e8b0f2fc220f7edc287a91ba45c76f6da1327405789dc61e31a649f57d6d93 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed6901a7cd973e880242b047fc86da03b498e8ed8e9838d6f3d107420dfcd9 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f642fb7c3aae91f49563f6ac1b84370b1c71b22b294ab8fbc0e3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466744cd29d79ec8af7a4cfe521cfe0f2b373b489b428532ebc08f0 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2d53813722d086e90ea67567c62e7363b8ac9207c580da580ef863a83ff27bcc1af9bbcbafee583d2692f2dfe82545cd693b7e89832715ec64be608745e0e529c0d90c60e037991dddd4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=84ae2612b7e30a08826858696ffe58b04409582f7f61a9fd89b8da7436540d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1909701a9f7ef6101bd2399cbdb58ce6a2fe375265d1b31599480046a21c40 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541d470c86e081f6c44d8b73ba2be130caf21500fe997f61f5d5ad +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846641d7543c89c33909dac24b427d715fc5b85633f07b6e1148b976 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b9cbb82dfbae55029e5f8fde96d8295f8e132adaf171665e7e1e2ae82598eeb32e9e7173605c5adb7581f57cfa5d89d24d2d7e8c228739a46f3fa0fe6261c0ee83b9d083fa913f88221a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=66909973ba7571691166adc1cba72feaf1870d0fe1a71372421114b227bafb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a6113e6302cfedcdc0439a2606a06d1a6f0053306d188a8d0aee1a630a5e15 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545be852e934eda94d7e61eaf39ea402c8db0c77433a9251cb654f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aa809bd7a0a842c28f35d10bc7cdfb061053952aaf8482c57e60 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=efe0329519660a84a2a418b869683458a06342db2cd97684000854900aa0274f907ff4a42648255711c7be088ad03d8c09f5ccd0fd217383120ea6a650101e5b09e4478d40bc614c6ad3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b9bad622368e64fbacab57ce79a664941d75ff62778de9757ca00f96ac58af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5d8a8111907d497e9905d883cfca75175f6bc39d0ae332fd3bdd6031d569cd + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254313d1c2a3e4aaebf8a13d13077b5d6aa7fd8cd93ada82e139ce9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663c387e2bc40b834219ff11f5ff429d83c9e01741eaa4435fe3eb +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7e44891d25df444c83119a57b2d12d38ba30c73ae1b3894959bde4a3beddeabd12aad42cd41d78dae898b163db19600f28c4e2910f865045f0341124d69b9f5b0cd2d2518ef701ce559d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=784797cf5ced552a14a2bce97597b2b65d3508f7aeca0bf669b54ffd1b6d71 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e5d7034b907fdced33489bb43015d216dad917aea17d4c410e24e5e6c0f24f + +handshake=Noise_XK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548d6383ab07befc895d34bfab2c20bb25 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667607d670be43da5c6ecbd567171a0113 +msg_2_payload= +msg_2_ciphertext=24a819b832ab7a11dd1464c2baf72f2c49e0665757911662ab11495a5fd4437e79e34779a2989c930f3b98e0fbc5dc1f059efd8983ccf4319dcdc99374e5d193 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e8b0f2fc220f7edc287a91ba45c76f6da1327405789dc61e31a649f57d6d93 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed6901a7cd973e880242b047fc86da03b498e8ed8e9838d6f3d107420dfcd9 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b813fb56423cef52924214450ca79a0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d81b686856f42a493326b1407010180e +msg_2_payload= +msg_2_ciphertext=2d53813722d086e90ea67567c62e7363b8ac9207c580da580ef863a83ff27bcc5a15b5094d3448614cf0e63d2dda3be9d3ba315f1f1a805c414db06ffe663fbd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=84ae2612b7e30a08826858696ffe58b04409582f7f61a9fd89b8da7436540d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1909701a9f7ef6101bd2399cbdb58ce6a2fe375265d1b31599480046a21c40 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b32bc1b6ebb0501ed71168bbdeeb9318 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c2e9c14cbb5200d147b6c8f489c05c42 +msg_2_payload= +msg_2_ciphertext=b9cbb82dfbae55029e5f8fde96d8295f8e132adaf171665e7e1e2ae82598eeb3c51ae537252a89cb6ceb1ecf331c89b3190c3517e90bff4ada05101678e8679d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=66909973ba7571691166adc1cba72feaf1870d0fe1a71372421114b227bafb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a6113e6302cfedcdc0439a2606a06d1a6f0053306d188a8d0aee1a630a5e15 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c75ef7d4eb006f9a21368b1260f350c9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466539edf21f03d684bfc564ebd12168bc1 +msg_2_payload= +msg_2_ciphertext=efe0329519660a84a2a418b869683458a06342db2cd97684000854900aa0274f593132dee4feea416b20df934a782f8de96321e62cc97693d5bf3521c64717a4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b9bad622368e64fbacab57ce79a664941d75ff62778de9757ca00f96ac58af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5d8a8111907d497e9905d883cfca75175f6bc39d0ae332fd3bdd6031d569cd + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254957d3b5c945018bb3bfe5ed1350eadcb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846664a86c797bdd9e60c061831340fa2afe +msg_2_payload= +msg_2_ciphertext=7e44891d25df444c83119a57b2d12d38ba30c73ae1b3894959bde4a3beddeabd0e05d74b64b68f9da9e4751f6eabac15bfc46a0e4909b3a90f6033848e316060 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=784797cf5ced552a14a2bce97597b2b65d3508f7aeca0bf669b54ffd1b6d71 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e5d7034b907fdced33489bb43015d216dad917aea17d4c410e24e5e6c0f24f + +handshake=Noise_XK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540c4e6c2fa1de96ff57949c01e13796236098242159a3226d7efc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e3186922b93e29c4a8f481bf540b7b9425152ed77d3ac32b6d5f +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=24a819b832ab7a11dd1464c2baf72f2c49e0665757911662ab11495a5fd4437e0fe2fb0506b390ab1e1527e2765e53dbed954c511b2929288a71525a716ce72aa94bca5bb136a6e3f02a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e8b0f2fc220f7edc287a91ba45c76f6da1327405789dc61e31a649f57d6d93 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ed6901a7cd973e880242b047fc86da03b498e8ed8e9838d6f3d107420dfcd9 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f642fb7c3aae91f49563f25c1b81e11ff9e6d6baaa12f93db4e8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466744cd29d79ec8af7a4cf81de742a83ee52d471a819e16e3d4a6d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2d53813722d086e90ea67567c62e7363b8ac9207c580da580ef863a83ff27bcc4568150efc37962fd4465366a61ebe29693b7e89832715ec64be7037e15af89fa2d1a1b6b34ff222e70f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=84ae2612b7e30a08826858696ffe58b04409582f7f61a9fd89b8da7436540d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1909701a9f7ef6101bd2399cbdb58ce6a2fe375265d1b31599480046a21c40 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541d470c86e081f6c44d8b89b84f8d57dae2408286970cef550461 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846641d7543c89c33909dac270471bfdfb14c212b05e9e1d89108c3c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b9cbb82dfbae55029e5f8fde96d8295f8e132adaf171665e7e1e2ae82598eeb3320cd9243495f571dc2b26a545c13efe4d2d7e8c228739a46f3fce27869ab41e1a1f674f9554ec4fc8be +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=66909973ba7571691166adc1cba72feaf1870d0fe1a71372421114b227bafb +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=a6113e6302cfedcdc0439a2606a06d1a6f0053306d188a8d0aee1a630a5e15 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545be852e934eda94d7e61afc8c49437cb522881b7b27897ae8443 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aa809bd7a0a842c28f350858fa12e20248091009ca7e2a5e1470 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=efe0329519660a84a2a418b869683458a06342db2cd97684000854900aa0274f701af0cafe1731d286886a8b99ef51ff09f5ccd0fd217383120e173a10693d93478e668e1f4db49fc09e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b9bad622368e64fbacab57ce79a664941d75ff62778de9757ca00f96ac58af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5d8a8111907d497e9905d883cfca75175f6bc39d0ae332fd3bdd6031d569cd + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254313d1c2a3e4aaebf8a13761a0eaa2344e96fa3cf99b0f43756f7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663c387e2bc40b834219ff7fd28443b5731f8122fee058af7270bd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7e44891d25df444c83119a57b2d12d38ba30c73ae1b3894959bde4a3beddeabd5d5617889062645c78eeb9ba04f1a58828c4e2910f865045f03473dcfec07ba5a485641d0cb0c8986388 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=784797cf5ced552a14a2bce97597b2b65d3508f7aeca0bf669b54ffd1b6d71 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e5d7034b907fdced33489bb43015d216dad917aea17d4c410e24e5e6c0f24f + +handshake=Noise_IK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544f8445e5dc2467b1e32653192d05dee85c4781bf0dd8d33ceebb5905a7a069f09e0d3f2cad1c842930a762eb75e52827f01d2c85189d527644b3221b4c3fc5cc +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aabfe2e5b1650bbaa88e33679893fc77 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=226ca869f2777611f37350a7ab446f650c0cfe2855b7f020ce658bcf100f2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=90d84d69cd44829283b05d684879b53b8d714e51619b601438a1ae67caacd9 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542723c3e2684abdc13656c8196a8dbd704eae2b5029b57d6f1387e1cf81cf8d968b42ff98eb66e9325f8a9bdf8f16f340c2cdae84d473830429e7d3e4b6731149 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846665a7ee5c74f123200a6d63a482c11412 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd57c203d5a1b8ae62c297614b5d71668c52ab4e70c1cbbc52c0538a069ccd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4cca33eb83505243974e576cbd818c98d3b346ff5c3374fac028ff153a4e9b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4a9c4176c417784b1ee28a0f323750682da959b44f9d8e06a07f757567492fa9c485c377303672a2809b5a5bb0f90133dfe4b427300d7bb2519877180db9826 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bd7e6a1364b08460dccf8961a117a93a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4492510a2b642757ad4089fda1333476635f5e8d984d8de917325a480380c8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e263d17ead44ed55677c2a12b11a3c9b625d3aa9f128b279cd5e281d5a8d9 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545bdb2d5031ac09dcb167ccedf2898899c56e3e963e1e707a4df1bed7f3f9594b80af8aa87faa8e0f7b1b9c32a49360cd3dbf48c162520192f875fbe743e38cea +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662a35d5a9542bd4d8d2f2f4f1784e9ba5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abbc8826715c00752948d22874560b57dc102dbf6c3dd853037efdd9499ad0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f80bad7ea7c64490f8123d2728a176c3afb97a59f197c7b1be246b7cd3eb1d + +handshake=Noise_IK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544f8445e5dc2467b1e32653192d05dee85c4781bf0dd8d33ceebb5905a7a069f09e0d3f2cad1c842930a762eb75e528270337527f958f92050deefa1892482d74328fee90d08201bba3cc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cb4a35db52355821787bb891112ba10f4d3dfe08b27d634db8af +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=226ca869f2777611f37350a7ab446f650c0cfe2855b7f020ce658bcf100f2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=90d84d69cd44829283b05d684879b53b8d714e51619b601438a1ae67caacd9 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542723c3e2684abdc13656c8196a8dbd704eae2b5029b57d6f1387e1cf81cf8d968b42ff98eb66e9325f8a9bdf8f16f3406cad606d45c38082aaf0636e8e77d36ee0b14bbd18c11b0fc688 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a3cacf615ab82f05d73a4699120208b2e421656f8dcba114854e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd57c203d5a1b8ae62c297614b5d71668c52ab4e70c1cbbc52c0538a069ccd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4cca33eb83505243974e576cbd818c98d3b346ff5c3374fac028ff153a4e9b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4a9c4176c417784b1ee28a0f323750682da959b44f9d8e06a07f757567492fa9c485c377303672a2809b5a5bb0f9013363eebbdb99964a60f81048f750a3e578d215067a83d2699d584 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e07ee913ea981e364239c3d829a9b1851d249f6fcd440f660431 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4492510a2b642757ad4089fda1333476635f5e8d984d8de917325a480380c8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e263d17ead44ed55677c2a12b11a3c9b625d3aa9f128b279cd5e281d5a8d9 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545bdb2d5031ac09dcb167ccedf2898899c56e3e963e1e707a4df1bed7f3f9594b80af8aa87faa8e0f7b1b9c32a49360cdd218fc428fc8457cdf1952ae4c8d5ba601f8bf9547bc4e3b5083 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b86d10d43f68d1d0667499f113d9a91c468559a52225e8f34d8c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abbc8826715c00752948d22874560b57dc102dbf6c3dd853037efdd9499ad0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f80bad7ea7c64490f8123d2728a176c3afb97a59f197c7b1be246b7cd3eb1d + +handshake=Noise_IK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544f8445e5dc2467b1e32653192d05dee85c4781bf0dd8d33ceebb5905a7a069f0d6bc97dbce6f8f0ee33d49311a72d0f8c4ef8ef3bc70ccb18fd61ad67dde7eda +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466787857f66c036e974ef9d6335d2ccc5f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=226ca869f2777611f37350a7ab446f650c0cfe2855b7f020ce658bcf100f2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=90d84d69cd44829283b05d684879b53b8d714e51619b601438a1ae67caacd9 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542723c3e2684abdc13656c8196a8dbd704eae2b5029b57d6f1387e1cf81cf8d96ae04ae107f5c4eac43b568cb7ee3bb0702cf064b9c887261c27b217dec189ba5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a5746ea5e335f63000f8f28190f79185 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd57c203d5a1b8ae62c297614b5d71668c52ab4e70c1cbbc52c0538a069ccd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4cca33eb83505243974e576cbd818c98d3b346ff5c3374fac028ff153a4e9b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4a9c4176c417784b1ee28a0f323750682da959b44f9d8e06a07f757567492fa875cb562717ab59a6cc44f6b90abbc692e57a72d368bbac4c15f2b26390fca38 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660a90cdf82790ca5709564a1a8ec6bd28 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4492510a2b642757ad4089fda1333476635f5e8d984d8de917325a480380c8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e263d17ead44ed55677c2a12b11a3c9b625d3aa9f128b279cd5e281d5a8d9 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545bdb2d5031ac09dcb167ccedf2898899c56e3e963e1e707a4df1bed7f3f9594b873a288972e606ec27a89d7805c31c4ce0ff7bf1ff67795d842e014a3c8ee6f7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb0445e37867bb67c516312c2a21c06f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abbc8826715c00752948d22874560b57dc102dbf6c3dd853037efdd9499ad0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f80bad7ea7c64490f8123d2728a176c3afb97a59f197c7b1be246b7cd3eb1d + +handshake=Noise_IK_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544f8445e5dc2467b1e32653192d05dee85c4781bf0dd8d33ceebb5905a7a069f0d6bc97dbce6f8f0ee33d49311a72d0f80337527f958f92050deee33c19777fa17306346367055751bb3f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cb4a35db52355821787bb67f33957e7809370c44d33538ad5a42 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=226ca869f2777611f37350a7ab446f650c0cfe2855b7f020ce658bcf100f2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=90d84d69cd44829283b05d684879b53b8d714e51619b601438a1ae67caacd9 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542723c3e2684abdc13656c8196a8dbd704eae2b5029b57d6f1387e1cf81cf8d96ae04ae107f5c4eac43b568cb7ee3bb076cad606d45c38082aaf08ff5dab57e5a624f16bf3630c2c5f104 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a3cacf615ab82f05d73a50c3841ebf6bba91d1631bb4a33552e6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fd57c203d5a1b8ae62c297614b5d71668c52ab4e70c1cbbc52c0538a069ccd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4cca33eb83505243974e576cbd818c98d3b346ff5c3374fac028ff153a4e9b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4a9c4176c417784b1ee28a0f323750682da959b44f9d8e06a07f757567492fa875cb562717ab59a6cc44f6b90abbc69363eebbdb99964a60f81d1bdca6741998d3df66cc4c3f7a20991 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e07ee913ea981e364239b86129146a0dcf47f65877606625369d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4492510a2b642757ad4089fda1333476635f5e8d984d8de917325a480380c8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e263d17ead44ed55677c2a12b11a3c9b625d3aa9f128b279cd5e281d5a8d9 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545bdb2d5031ac09dcb167ccedf2898899c56e3e963e1e707a4df1bed7f3f9594b873a288972e606ec27a89d7805c31c4cd218fc428fc8457cdf1976bed363286c0e199a5df2a8dc631f33 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b86d10d43f68d1d06674b4ceee887769c53e3b7a239e76287e1f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abbc8826715c00752948d22874560b57dc102dbf6c3dd853037efdd9499ad0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f80bad7ea7c64490f8123d2728a176c3afb97a59f197c7b1be246b7cd3eb1d + +handshake=Noise_XX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663414af878d3e46a2f58911a816d6e8346d4ea17a6f2a0bb4ef4ed56c133cff4560a34e36ea82109f26cf2e5a5caf992b608d55c747f615e5a3425a7a19eefb8f +msg_2_payload= +msg_2_ciphertext=87f864c11ba449f46a0a4f4e2eacbb7b0457784f4fca1937f572c93603e9c4d97e5ea11b16f3968710b23a3be3202dc1b5e1ce3c963347491e74f5c0768a9b42 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a52ef02ba60e12696d1d6b9ef4245c88fca757b6134ad6e76b56e310a6adf6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2445aa438ebd649281c636cc7269ca82f1d9023d72520943aeabf909cdf521 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254555f63b2499511e3b299a5649351a5b7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622df46c0ac1e0fc71795a84e37cc0e963d131c8e84c02cd5cfcfe8def3fe128b324ab54fd3be59ac143dfdc68996211170078c960e051d6ed971da20bde0fcf1 +msg_2_payload= +msg_2_ciphertext=462127adbe047db3d1fce0581b5447d99b606c591545a7719132e0c91fe93d123be3fe89ffd8af56e02cefda863080ecee5651dcecddde76b8237c66740d7c8f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=75fff8afebd2f14da1cac9cc5b5201395cdf2ad65f3a97804e360c16f4e2ac +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=150cc85f79f9ca0f0730b8b4707805ed1969ff6b2770a5d466cd2754802805 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549f27cade2b6f2db14f582e49cfbfc068 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f0f30704cd806d42849595f4e39d8ace7b1f7ab9c62c9ccaf7284b3d8ce0d88286de6a5c75efd3ada339fd7ba335dee5fe0151a61f7decdabe8fab42d807358 +msg_2_payload= +msg_2_ciphertext=3709db3d2b87c711bdd3ef87e62edd8a2775482a4421a58fb5eeb106861e98d24c021634f68b6fa8a9c2f48161e190714c2a2d90a55d2dc32f33fcbaf5afc67c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=61eaa2290029bcde241e90efb965beeb7837ec5441928800275670fdb058de +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ee55ef942191e45cf5bcea014c4a0c71f0780ff6095ff93f467e7a746e264c + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625462f2d89ffb750657573d23edc7c79728 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9996f0e38eded0281a0f505a4f2473b114924724e374c408b3ba103abc7ffbf72bf9b5f5f37f1a8ee33e4708c1f35d54d93fc2a553004be11b9a6ad56d03f30 +msg_2_payload= +msg_2_ciphertext=4744625f46dfce9240a5b1927393fd862a2520366f4df66de4b75019d201de92f3bd1d11aef54b65374c268c0ec19d34ec1fff795f07ef7065932e5983ee2e84 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=70847317d915af289e3ff17e5d66e4b4b0020d1bd997b8bb17cfa15710db0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ad071b14d700e2789c1251f57e3b1e455e3f3be012d7ab6abce986b536ba21 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254648d756cb03de7ad06e87f9a577c00de +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846696a7a5454cc70bb4eec2a2f7c616c143564ff1ae149458f9e70afb3498be7a88c9feda8ece3bb7d846bd57a37fc9cf362b7d090998d862bd82fcf9a19cf154e1 +msg_2_payload= +msg_2_ciphertext=f5b6224ea13577089dc14b20ca8e90d0cedede4faff50348d4d0a0f941182ad787d1e72132665f8402f660af90e07e671606bb5a4931d244dfa6590809fac237 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5e80fec73b32f6ff466aa5addbc2b16e2cf062f09c36796ecb2efcc35cac99 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=df3c8983cb9f286df65e57d0010dc65eeca3bca44b6b240da8ebf92be581cd + +handshake=Noise_XX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663414af878d3e46a2f58911a816d6e8346d4ea17a6f2a0bb4ef4ed56c133cff4572e7a2ba5123ac30618b3d205f5c2d17f50cbca216483ac56bcc78e33bf520303278db641e5e731b2e3a +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=87f864c11ba449f46a0a4f4e2eacbb7b0457784f4fca1937f572c93603e9c4d9f27e318e43ba630594c4d08eeb3b36d97c7377a2f4f9144b2f0c8095ad92140505b2ab53eff244b14138 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a52ef02ba60e12696d1d6b9ef4245c88fca757b6134ad6e76b56e310a6adf6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2445aa438ebd649281c636cc7269ca82f1d9023d72520943aeabf909cdf521 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f533cf20723ac4407c8e51516d7c7382d8aa777424dba78813d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622df46c0ac1e0fc71795a84e37cc0e963d131c8e84c02cd5cfcfe8def3fe128b1146c1820dc4d08bf16b5c682badf2ef2dc6c1642ae7e8ae8c8e1e38a06064341a604c21b70227181c04 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=462127adbe047db3d1fce0581b5447d99b606c591545a7719132e0c91fe93d122132c2cde2bc69209884f77756f265744111b0bfa4fdeb4704a42c7f8750279908327b545416cf81f828 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=75fff8afebd2f14da1cac9cc5b5201395cdf2ad65f3a97804e360c16f4e2ac +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=150cc85f79f9ca0f0730b8b4707805ed1969ff6b2770a5d466cd2754802805 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625409f815b8eb0dbb46e73f8ce514a7791c712e94ffe307fd7bdd4a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f0f30704cd806d42849595f4e39d8ace7b1f7ab9c62c9ccaf7284b3d8ce0d88a5374047a547b592a9391e74bfd6c960d6a978c9e0cba95a40c5c091ef030556a3b10bd4c6c77fd99d75 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3709db3d2b87c711bdd3ef87e62edd8a2775482a4421a58fb5eeb106861e98d238c8b1696e695be5da9242acf392b5f4bc587962ef21463d1a0691f4042790868d59492e1d9e75a7787e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=61eaa2290029bcde241e90efb965beeb7837ec5441928800275670fdb058de +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ee55ef942191e45cf5bcea014c4a0c71f0780ff6095ff93f467e7a746e264c + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544968e874077ca381c1f03927174d090dc0c513b1eae87abbd728 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9996f0e38eded0281a0f505a4f2473b114924724e374c408b3ba103abc7ffbf8b7a8d7dff4aabdae96b83924c164accf0e6d093aa11303cacf7f18b3898ffa9cf9491aa2cd3174edfca +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4744625f46dfce9240a5b1927393fd862a2520366f4df66de4b75019d201de92d10c61a7bd2f3d460924354137751a0dd24b1336d8119acacd578c7bd6c02cd1d839990b572e4fd78e8a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=70847317d915af289e3ff17e5d66e4b4b0020d1bd997b8bb17cfa15710db0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ad071b14d700e2789c1251f57e3b1e455e3f3be012d7ab6abce986b536ba21 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254653658a6a90feb6404ce396c157f0cbec50fbaf2015658068d1d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846696a7a5454cc70bb4eec2a2f7c616c143564ff1ae149458f9e70afb3498be7a885650c9453eb8927a88bd3f8cac964759dde1bfec74551b1f083a60ac9c0c8a1d5e96dedbdc3c38ab235a +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f5b6224ea13577089dc14b20ca8e90d0cedede4faff50348d4d0a0f941182ad72fbb6b3609cbfa5bc7a578aa8c377e42734c20e3dd6c03cf438ae0fb6d287fa76ca661ba86195afa81c9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5e80fec73b32f6ff466aa5addbc2b16e2cf062f09c36796ecb2efcc35cac99 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=df3c8983cb9f286df65e57d0010dc65eeca3bca44b6b240da8ebf92be581cd + +handshake=Noise_XX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663414af878d3e46a2f58911a816d6e8346d4ea17a6f2a0bb4ef4ed56c133cff4588f043d1e49a3289b1beeab8f96b0551a48cddf9f38b1a12e46c6908644198f3 +msg_2_payload= +msg_2_ciphertext=87f864c11ba449f46a0a4f4e2eacbb7b0457784f4fca1937f572c93603e9c4d95a04fa1f1c41fb3f00d496f242c1e44ce5b749b3d54bf74cea2dad086d601fb6 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a52ef02ba60e12696d1d6b9ef4245c88fca757b6134ad6e76b56e310a6adf6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2445aa438ebd649281c636cc7269ca82f1d9023d72520943aeabf909cdf521 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625454a218352d64c1f8c239416ccb542aec +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622df46c0ac1e0fc71795a84e37cc0e963d131c8e84c02cd5cfcfe8def3fe128b58733b0ab529b3f48ed3fbe90840f1a27404f52be696831ccb795d1bdee31d33 +msg_2_payload= +msg_2_ciphertext=462127adbe047db3d1fce0581b5447d99b606c591545a7719132e0c91fe93d12fb91ca67cf72f381bab072bd9e6efef157067416654408489b43ba2fb6173b66 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=75fff8afebd2f14da1cac9cc5b5201395cdf2ad65f3a97804e360c16f4e2ac +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=150cc85f79f9ca0f0730b8b4707805ed1969ff6b2770a5d466cd2754802805 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254441dc6d59be427b50c47033cb28b1c92 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f0f30704cd806d42849595f4e39d8ace7b1f7ab9c62c9ccaf7284b3d8ce0d88e1c910791fa4ba183633c2d95c5511f60fe2e339a2e21ec0a6a603fa905d0531 +msg_2_payload= +msg_2_ciphertext=3709db3d2b87c711bdd3ef87e62edd8a2775482a4421a58fb5eeb106861e98d28aff4797b2780ca5d92c6497403bc2b0f953fee8dc7394a793f853dd11a05bac +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=61eaa2290029bcde241e90efb965beeb7837ec5441928800275670fdb058de +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ee55ef942191e45cf5bcea014c4a0c71f0780ff6095ff93f467e7a746e264c + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e93da98d3dd0111950d413e23d3e1a83 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9996f0e38eded0281a0f505a4f2473b114924724e374c408b3ba103abc7ffbfe9dfce15c311b11d4afa7fe50516980d178eca6d8594391837b5aab867168be5 +msg_2_payload= +msg_2_ciphertext=4744625f46dfce9240a5b1927393fd862a2520366f4df66de4b75019d201de924ab1208d037ee21e2d2f9cfd17678f49bf474350e7da4ef109e569e66507b8b0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=70847317d915af289e3ff17e5d66e4b4b0020d1bd997b8bb17cfa15710db0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ad071b14d700e2789c1251f57e3b1e455e3f3be012d7ab6abce986b536ba21 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545e4d090b68903a328013b0fa37a209a1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846696a7a5454cc70bb4eec2a2f7c616c143564ff1ae149458f9e70afb3498be7a886885719af8aa799a244c80558b556ef67ec5874230e5290454ca35afef8df8d3 +msg_2_payload= +msg_2_ciphertext=f5b6224ea13577089dc14b20ca8e90d0cedede4faff50348d4d0a0f941182ad72a09d91f8664f8edfd904cb24e0666f9f40168c1c94b381251b6ca43dad53170 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5e80fec73b32f6ff466aa5addbc2b16e2cf062f09c36796ecb2efcc35cac99 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=df3c8983cb9f286df65e57d0010dc65eeca3bca44b6b240da8ebf92be581cd + +handshake=Noise_XX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663414af878d3e46a2f58911a816d6e8346d4ea17a6f2a0bb4ef4ed56c133cff4545958c588d17d6373e0c1dcfa3755d37f50cbca216483ac56bcc98f5095870aa814ba40c08079c11f087 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=87f864c11ba449f46a0a4f4e2eacbb7b0457784f4fca1937f572c93603e9c4d9c1e9a1a313d02b78871cfd178a521a4c7c7377a2f4f9144b2f0ccedc84d379151b466741e4b266db6023 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=a52ef02ba60e12696d1d6b9ef4245c88fca757b6134ad6e76b56e310a6adf6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=2445aa438ebd649281c636cc7269ca82f1d9023d72520943aeabf909cdf521 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f533cf20723ac4407c87f43dc5dc6f6d1867a322a706af81adb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622df46c0ac1e0fc71795a84e37cc0e963d131c8e84c02cd5cfcfe8def3fe128b59d623ffc18ae67b1acba43eb87910b02dc6c1642ae7e8ae8c8e861ed15d8d6b65ff99f73d8286cc9819 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=462127adbe047db3d1fce0581b5447d99b606c591545a7719132e0c91fe93d1294b31017013e8ac0a697b42922a5fe204111b0bfa4fdeb4704a4b5492137b40088f810ee4d1a58882e25 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=75fff8afebd2f14da1cac9cc5b5201395cdf2ad65f3a97804e360c16f4e2ac +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=150cc85f79f9ca0f0730b8b4707805ed1969ff6b2770a5d466cd2754802805 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625409f815b8eb0dbb46e73ff10061ce4f668e7ad525d48d24612e49 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f0f30704cd806d42849595f4e39d8ace7b1f7ab9c62c9ccaf7284b3d8ce0d887fbc3e2f5ffd90a03e00af190dfee90ad6a978c9e0cba95a40c5af61409fd89acea9efe61cc3c5626453 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3709db3d2b87c711bdd3ef87e62edd8a2775482a4421a58fb5eeb106861e98d2840ca8244e6063975c878004aa7ee991bc587962ef21463d1a0615316bea7af1a6b102acfd9bc4e8b07e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=61eaa2290029bcde241e90efb965beeb7837ec5441928800275670fdb058de +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ee55ef942191e45cf5bcea014c4a0c71f0780ff6095ff93f467e7a746e264c + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544968e874077ca381c1f0127df29420b859cf36b5383c2d8d986b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9996f0e38eded0281a0f505a4f2473b114924724e374c408b3ba103abc7ffbf8bc919f41c651555a9d4d5809975e676f0e6d093aa11303cacf701682c1dadd3666c1e965a3158618a30 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4744625f46dfce9240a5b1927393fd862a2520366f4df66de4b75019d201de92891230ebf50cc2d52029ad960d7fa613d24b1336d8119acacd5745ce1ba24faa91d6cf7be217ff6799ad +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=70847317d915af289e3ff17e5d66e4b4b0020d1bd997b8bb17cfa15710db0b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ad071b14d700e2789c1251f57e3b1e455e3f3be012d7ab6abce986b536ba21 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254653658a6a90feb6404ce2902887f0faf388ff019393d23fd4976 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846696a7a5454cc70bb4eec2a2f7c616c143564ff1ae149458f9e70afb3498be7a886ed5d694d493c5867cb2c232205e46bddde1bfec74551b1f083a86e220331181777ca16a1bad616dff5f +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f5b6224ea13577089dc14b20ca8e90d0cedede4faff50348d4d0a0f941182ad7e65025d045c6ff1f63a8b63ffe90710e734c20e3dd6c03cf438a6ce9aa9775b05dd5d3b729a9ac78d811 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=5e80fec73b32f6ff466aa5addbc2b16e2cf062f09c36796ecb2efcc35cac99 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=df3c8983cb9f286df65e57d0010dc65eeca3bca44b6b240da8ebf92be581cd + +handshake=Noise_IX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466baeb82eef5d1debeac9be97240e60145fdad9ac337e2baa15d6854385bd82377fcf6c76dd0c35c7f0584b41c85d1755ee1f64c58f0abf28c8fb79b1c0cd572a6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ef23146b5edecd2339995fe7f8c597ffa673d06b2671a323d881b1c39f5cef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9fb1b190c31c93d2822df95c20f1117eb3f4c2999c51d704e855f30458bfb7 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a5fcb82f22fdab798026f0ccb9a6b6ce96e3facfeae51b2908db5b849c0c78cc9bda6dc05a548079571ea4f597884520ecaf65860091dada12b09c4fd30ebb0c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466661e5bec7e323f7e6117cdeef3622006331b5aad001e33c600478db7b40375e92db6dd6a1dcc1e7e3e32d0d959f2ac8d568d7c482043bf965577f51ca516a3ed +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=74de2cd580b07af1ec00ef46206cf8eabb9cd289c10eee2b37e25978fd7748 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db8795447bbc6d58b7b3d37814c8c351d8dcbeba8e201c2e5f5af7978d1e32 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545667d83bcfa7dbb6ee159dde3afffea915ce4084462fc02f7f7dc86c2d338a9877fda5a8ccdda8ad14afbfc2708af4a4b210164cc720e7ec1a915daafebc046a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f04c5f04c9ae8992c210cb0193a52ae8c081c44f33ab1490df3e3c344eb1457cdf92517e1a679b2db5c4b7c71e3f6ec7452bb6a2cd4d989ac3ca0f1ec97974f4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b2590aa4f81a2fbc961d60abede55cc6a4a64a40f7bcd1642f0a31daace3fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=82b96b24e3c63563ddab16453506322429609077c4182022c6b9ed126e172a + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a4ef04eabc08e997b45b56825904b887b21cd99b04ad3be0304d7f2f81aac60b41283ee452d1546934cac576e8955322e1252e893e3e959ff36ada8319d66a9c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a3ea1d0b422826e11b94b492b338fd5ef4f90d1a91a637e37c10d0ff7df19c2bdd0ced026d6c2a81cd55b68e7ec63f0f8eff1e2c8cc593e2f36ad5b936a2114a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c6623366838f79936add41938a2f31cc6703b7e7cebc2ec958f116a45842ae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c84d7d2f82cc2bf54b06aef1e2bf49bec5305d72fb5fd19754a3dce298c74 + +handshake=Noise_IX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466baeb82eef5d1debeac9be97240e60145fdad9ac337e2baa15d6854385bd823772aaa75c6cb27ba27acecd7fc13321c5b9ddfb64a50666d8ca7cbdf3fba5ccc87407789e701a194fb7074 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ef23146b5edecd2339995fe7f8c597ffa673d06b2671a323d881b1c39f5cef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9fb1b190c31c93d2822df95c20f1117eb3f4c2999c51d704e855f30458bfb7 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a5fcb82f22fdab798026f0ccb9a6b6ce96e3facfeae51b2908db5b849c0c78cc9bda6dc05a548079571ea4f597884520b4de8177eb0303296be6e30ab7d21fecf59931884498725a1dfa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466661e5bec7e323f7e6117cdeef3622006331b5aad001e33c600478db7b40375e9be6315eee09348312435e12a927633c97ee6317754ea54d27027f3a339474da27661a016ba09d64d389d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=74de2cd580b07af1ec00ef46206cf8eabb9cd289c10eee2b37e25978fd7748 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db8795447bbc6d58b7b3d37814c8c351d8dcbeba8e201c2e5f5af7978d1e32 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545667d83bcfa7dbb6ee159dde3afffea915ce4084462fc02f7f7dc86c2d338a9877fda5a8ccdda8ad14afbfc2708af4a4fad9d759fcfb82f875d04a0b6ef6b58b9b8e94892f6f41c64ad7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f04c5f04c9ae8992c210cb0193a52ae8c081c44f33ab1490df3e3c344eb1457c03cc143af8a7a996dfada325c42dfa443aabe1beb17534cca091197b65ea331e7cdb9846e2d55825db62 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b2590aa4f81a2fbc961d60abede55cc6a4a64a40f7bcd1642f0a31daace3fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=82b96b24e3c63563ddab16453506322429609077c4182022c6b9ed126e172a + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a4ef04eabc08e997b45b56825904b887b21cd99b04ad3be0304d7f2f81aac60b41283ee452d1546934cac576e895532296a873828dcafe77b1f902e978dd2aaca2da191591f1ed576d41 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a3ea1d0b422826e11b94b492b338fd5ef4f90d1a91a637e37c10d0ff7df19c2bf798adb221973ad40ff6bce68049acc745ebeb84d712067b160edcf4970d12bda37dbeacc9b95197d871 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c6623366838f79936add41938a2f31cc6703b7e7cebc2ec958f116a45842ae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c84d7d2f82cc2bf54b06aef1e2bf49bec5305d72fb5fd19754a3dce298c74 + +handshake=Noise_IX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466baeb82eef5d1debeac9be97240e60145fdad9ac337e2baa15d6854385bd823773396a0eee6acf05ca7aa5378bf4288454fc680db8e956a38853e04e6014dce60 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ef23146b5edecd2339995fe7f8c597ffa673d06b2671a323d881b1c39f5cef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9fb1b190c31c93d2822df95c20f1117eb3f4c2999c51d704e855f30458bfb7 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a5fcb82f22fdab798026f0ccb9a6b6ce96e3facfeae51b2908db5b849c0c78cc832059e6aa8a847f2d0f96394e935903a7b5bdc38dc307c36c560744dedf674c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466661e5bec7e323f7e6117cdeef3622006331b5aad001e33c600478db7b40375e9fd6d8b2f9574f9ea404a6ecbeb282f8f112e62e65ae0c5117a2409ffdd9c87bd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=74de2cd580b07af1ec00ef46206cf8eabb9cd289c10eee2b37e25978fd7748 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db8795447bbc6d58b7b3d37814c8c351d8dcbeba8e201c2e5f5af7978d1e32 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545667d83bcfa7dbb6ee159dde3afffea915ce4084462fc02f7f7dc86c2d338a98e01aeac3a330e93ed7024c2417abe12b8b941d28126267f9ec338fb268badb92 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f04c5f04c9ae8992c210cb0193a52ae8c081c44f33ab1490df3e3c344eb1457c60a8f15129cf89e14206666494b093758fbe507fcae17bee288b08f9c85ee4eb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b2590aa4f81a2fbc961d60abede55cc6a4a64a40f7bcd1642f0a31daace3fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=82b96b24e3c63563ddab16453506322429609077c4182022c6b9ed126e172a + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a4ef04eabc08e997b45b56825904b887b21cd99b04ad3be0304d7f2f81aac60bee28a96afdcf5ddb9834f24b3adbca9ffb34820535b9ef395d9ec74be0b6c463 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a3ea1d0b422826e11b94b492b338fd5ef4f90d1a91a637e37c10d0ff7df19c2bdf754927b06ad75f9854618fc90be5bfa7832aea81c319f6f370c0ea61c71610 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c6623366838f79936add41938a2f31cc6703b7e7cebc2ec958f116a45842ae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c84d7d2f82cc2bf54b06aef1e2bf49bec5305d72fb5fd19754a3dce298c74 + +handshake=Noise_IX_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466baeb82eef5d1debeac9be97240e60145fdad9ac337e2baa15d6854385bd823778a69f5de7c91c7049e8a7deb8f146a4f9ddfb64a50666d8ca7cb72de7c28b6e89745666dda39138f879b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ef23146b5edecd2339995fe7f8c597ffa673d06b2671a323d881b1c39f5cef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9fb1b190c31c93d2822df95c20f1117eb3f4c2999c51d704e855f30458bfb7 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a5fcb82f22fdab798026f0ccb9a6b6ce96e3facfeae51b2908db5b849c0c78cc832059e6aa8a847f2d0f96394e935903b4de8177eb0303296be67e9e3ad1409bd062f3aba1c7c477040b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466661e5bec7e323f7e6117cdeef3622006331b5aad001e33c600478db7b40375e9737c4d6dd044d38d9ffd2dd2dab050917ee6317754ea54d2702741888f20c82d956a7bb993de16de0d14 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=74de2cd580b07af1ec00ef46206cf8eabb9cd289c10eee2b37e25978fd7748 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db8795447bbc6d58b7b3d37814c8c351d8dcbeba8e201c2e5f5af7978d1e32 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545667d83bcfa7dbb6ee159dde3afffea915ce4084462fc02f7f7dc86c2d338a98e01aeac3a330e93ed7024c2417abe12bfad9d759fcfb82f875d0c8a2111c403741010bf0636ee681033a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f04c5f04c9ae8992c210cb0193a52ae8c081c44f33ab1490df3e3c344eb1457c5132a645f88ee1276193c0bcb3c09d433aabe1beb17534cca09105fea7ab6384f007948b20ea8639f0cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b2590aa4f81a2fbc961d60abede55cc6a4a64a40f7bcd1642f0a31daace3fd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=82b96b24e3c63563ddab16453506322429609077c4182022c6b9ed126e172a + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a4ef04eabc08e997b45b56825904b887b21cd99b04ad3be0304d7f2f81aac60bee28a96afdcf5ddb9834f24b3adbca9f96a873828dcafe77b1f9e3d5a83968ebd8ec79b57e9771a568f5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a3ea1d0b422826e11b94b492b338fd5ef4f90d1a91a637e37c10d0ff7df19c2b0099aaa3c996f372406528a3a794d3ff45ebeb84d712067b160e85632580c15161e5fa9cc27ac7e74016 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c6623366838f79936add41938a2f31cc6703b7e7cebc2ec958f116a45842ae +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4c84d7d2f82cc2bf54b06aef1e2bf49bec5305d72fb5fd19754a3dce298c74 + +handshake=Noise_N_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625466758477eb5e8e0b273460a89ef8d8bb +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e89db912502b14e9dbf21dc062b494ac2e25f2010ba86f246759fdb8bd990 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=505ffc87ec9cca139162b049416af8ca811e7044897d399912f9a139ac65ec + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625404ec6da801ab66f5e59f874f002af309 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bf4151a9d4b9f4250c91542ee802a0701692a141344edb1ef3e831a8210e1c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c1dc8651b5c1d3f4189f858a7972bfd62a4123530c64d4239457fa7e46c10a + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546d32a96bccf7b2b063e7745276a99f6e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6b24bc0b584f4ca451495cdddeed74727d03f88fc561227b4cf2486f3bb360 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=60f010c122da08e08781f409477350a6da336e03bf3eb266693b581dd61826 + +handshake=Noise_N_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a703e3bfcc38dbdb465b7d5ded3686008b3ff4c92f20e9fe4b44 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e89db912502b14e9dbf21dc062b494ac2e25f2010ba86f246759fdb8bd990 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=505ffc87ec9cca139162b049416af8ca811e7044897d399912f9a139ac65ec + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625457027708cda785ef784def1e032c2ffbbcbed3108edbbb565140 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bf4151a9d4b9f4250c91542ee802a0701692a141344edb1ef3e831a8210e1c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c1dc8651b5c1d3f4189f858a7972bfd62a4123530c64d4239457fa7e46c10a + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625407e786c1a8d1e6880cf0c8ce414c8d2dbf57be2fd7c3152586df +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6b24bc0b584f4ca451495cdddeed74727d03f88fc561227b4cf2486f3bb360 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=60f010c122da08e08781f409477350a6da336e03bf3eb266693b581dd61826 + +handshake=Noise_N_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625439e0d27ade0e68178eedc32a520154b9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e89db912502b14e9dbf21dc062b494ac2e25f2010ba86f246759fdb8bd990 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=505ffc87ec9cca139162b049416af8ca811e7044897d399912f9a139ac65ec + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c1180d93ec09b5da7a888f7b5b9e9d6e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bf4151a9d4b9f4250c91542ee802a0701692a141344edb1ef3e831a8210e1c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c1dc8651b5c1d3f4189f858a7972bfd62a4123530c64d4239457fa7e46c10a + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547d8ce635d32999d4ca2bb00175c04248 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6b24bc0b584f4ca451495cdddeed74727d03f88fc561227b4cf2486f3bb360 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=60f010c122da08e08781f409477350a6da336e03bf3eb266693b581dd61826 + +handshake=Noise_N_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a703e3bfcc38dbdb465bc83726dbcf8aa4764c684931d2985245 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e89db912502b14e9dbf21dc062b494ac2e25f2010ba86f246759fdb8bd990 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=505ffc87ec9cca139162b049416af8ca811e7044897d399912f9a139ac65ec + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625457027708cda785ef784de0eed7a36afc2fad22523e691cd155e5 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=bf4151a9d4b9f4250c91542ee802a0701692a141344edb1ef3e831a8210e1c +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c1dc8651b5c1d3f4189f858a7972bfd62a4123530c64d4239457fa7e46c10a + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA256 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625407e786c1a8d1e6880cf049f2b82299602ae37ab12f077040a55a +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6b24bc0b584f4ca451495cdddeed74727d03f88fc561227b4cf2486f3bb360 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=60f010c122da08e08781f409477350a6da336e03bf3eb266693b581dd61826 + +handshake=Noise_K_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254af724161ce8037f690f587990caba741 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=af4b5c9ff0d0b31da602bb6e7153edd095bd37fa83b0a35768d6ac024bc746 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a5f0b377dfd3489f3f151959508a84f19530d5cb0ea8226f2481f7839d2be5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547a2e747346812f333b2884928033af07 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=548e6dc3b25bc8d0916603d1b74d6755aeb9664c5d890466d385e7dc918acb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b43de84e2dbaaa14fdec24a4f7cc2dad954be8427ffea5b736d623b75ac878 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543754db2fc9cc2ef2f59756219f19fdf4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8c47be8aaf7c41ae38280e5e38cd42f5c57e55f0bae05b5088c448ca737cac +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03fac31b503fe58810962b52ddd9ad9fb8ff709d88926115d593bb790be465 + +handshake=Noise_K_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b8cae311a5f3367e2170caf5c7ae0947b49ced8a3b7a99f10460 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=af4b5c9ff0d0b31da602bb6e7153edd095bd37fa83b0a35768d6ac024bc746 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a5f0b377dfd3489f3f151959508a84f19530d5cb0ea8226f2481f7839d2be5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541a844cd1a19651421cc5f0a672d6629f1bcebe5fd2691c65df09 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=548e6dc3b25bc8d0916603d1b74d6755aeb9664c5d890466d385e7dc918acb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b43de84e2dbaaa14fdec24a4f7cc2dad954be8427ffea5b736d623b75ac878 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542e79d636b2cfc26e6d3b795a2db7f448dd03f4a5053d35f31b5e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8c47be8aaf7c41ae38280e5e38cd42f5c57e55f0bae05b5088c448ca737cac +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03fac31b503fe58810962b52ddd9ad9fb8ff709d88926115d593bb790be465 + +handshake=Noise_K_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254061ee6934752ad8113f86fbb135a5833 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=af4b5c9ff0d0b31da602bb6e7153edd095bd37fa83b0a35768d6ac024bc746 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a5f0b377dfd3489f3f151959508a84f19530d5cb0ea8226f2481f7839d2be5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548960d9a2b168215cea4307684febf3a7 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=548e6dc3b25bc8d0916603d1b74d6755aeb9664c5d890466d385e7dc918acb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b43de84e2dbaaa14fdec24a4f7cc2dad954be8427ffea5b736d623b75ac878 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fffe9d4e3bde9e0560276f13d2c04674 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8c47be8aaf7c41ae38280e5e38cd42f5c57e55f0bae05b5088c448ca737cac +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03fac31b503fe58810962b52ddd9ad9fb8ff709d88926115d593bb790be465 + +handshake=Noise_K_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b8cae311a5f3367e21709e6be52d6fd8abf20e2708f50165f7ba +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=af4b5c9ff0d0b31da602bb6e7153edd095bd37fa83b0a35768d6ac024bc746 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=a5f0b377dfd3489f3f151959508a84f19530d5cb0ea8226f2481f7839d2be5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541a844cd1a19651421cc510d96aa4ac452dc98839e9311bb36fd9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=548e6dc3b25bc8d0916603d1b74d6755aeb9664c5d890466d385e7dc918acb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b43de84e2dbaaa14fdec24a4f7cc2dad954be8427ffea5b736d623b75ac878 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542e79d636b2cfc26e6d3b936366095e5a0447b667b6c1ae8d7887 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8c47be8aaf7c41ae38280e5e38cd42f5c57e55f0bae05b5088c448ca737cac +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=03fac31b503fe58810962b52ddd9ad9fb8ff709d88926115d593bb790be465 + +handshake=Noise_X_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548cccfba3094925ef50f41bb45d6e69936ad15fcba0c3479a46afb577d3459497de729f4d8d615d5886e52f4f888dd49490ed46957206fa937490058feca88e4c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e04749040fde470ab93dda9ca2d7dc69896d0c564d0898755a09830735187 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=11ca4c30bd3b563c23f5a5ae83844d038b1ae8ac7ed4e7e788ad9cdfb56c39 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546a25d60fc3551b45b422660fc5330a9a9a211a4c015192a4cb45f9e2736c0e75bb78c9f2817412a0d0644ce590aa15f91ed91cc1bf4db059be00aaea12d8ee2e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6f84a4ede3160b3464efec0b87051e3555832871ffb6b3f3549461507068cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=83ac689c3ac344c2b7fbbaacc8d655c9ff0a1a89458b12ceb4510e80b5f9da + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625433e53e3ef1c689e4802f9453dd73c9402aa8072a810f934f7a466d2ede7d8ca7f8d22e80734349ab2e4fef536d0bc40c860a78498c16248c6d4121c7c68cd5e9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=131094feaa8cbacb6c348050711162cf8d44b13e8de882c98410e7d3981d51 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=15fcd4e117342b9e651d6ab5048fd549fb38093e21fd369e1c6e630fbe9d24 + +handshake=Noise_X_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548cccfba3094925ef50f41bb45d6e69936ad15fcba0c3479a46afb577d3459497de729f4d8d615d5886e52f4f888dd49486d56a823c51b82cc9bbf955b0358da74bdd0b077ee1f02b887f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e04749040fde470ab93dda9ca2d7dc69896d0c564d0898755a09830735187 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=11ca4c30bd3b563c23f5a5ae83844d038b1ae8ac7ed4e7e788ad9cdfb56c39 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546a25d60fc3551b45b422660fc5330a9a9a211a4c015192a4cb45f9e2736c0e75bb78c9f2817412a0d0644ce590aa15f961bd13d0da02b4849bacd8ac61dcfa5bef1e7f6befb9ccdb30c1 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6f84a4ede3160b3464efec0b87051e3555832871ffb6b3f3549461507068cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=83ac689c3ac344c2b7fbbaacc8d655c9ff0a1a89458b12ceb4510e80b5f9da + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625433e53e3ef1c689e4802f9453dd73c9402aa8072a810f934f7a466d2ede7d8ca7f8d22e80734349ab2e4fef536d0bc40c425ca4e756799dee05a7ed4e89dfa0920c4a847773f25c044e12 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=131094feaa8cbacb6c348050711162cf8d44b13e8de882c98410e7d3981d51 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=15fcd4e117342b9e651d6ab5048fd549fb38093e21fd369e1c6e630fbe9d24 + +handshake=Noise_X_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548cccfba3094925ef50f41bb45d6e69936ad15fcba0c3479a46afb577d3459497a2b1b0c7f3c1107df1feeb7d2e340fd8d5f49ce97438f6953faa0fd6fa333a9e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e04749040fde470ab93dda9ca2d7dc69896d0c564d0898755a09830735187 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=11ca4c30bd3b563c23f5a5ae83844d038b1ae8ac7ed4e7e788ad9cdfb56c39 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546a25d60fc3551b45b422660fc5330a9a9a211a4c015192a4cb45f9e2736c0e75f6af9abf7f31d35f75534eac6e1181ed73faa6a26a1c01055d98b0f42b3e70d6 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6f84a4ede3160b3464efec0b87051e3555832871ffb6b3f3549461507068cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=83ac689c3ac344c2b7fbbaacc8d655c9ff0a1a89458b12ceb4510e80b5f9da + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625433e53e3ef1c689e4802f9453dd73c9402aa8072a810f934f7a466d2ede7d8ca79f78c9011a748444af8a1d2ac4beffd3606f6e6109b0940a1b63b3f6d67e62d9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=131094feaa8cbacb6c348050711162cf8d44b13e8de882c98410e7d3981d51 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=15fcd4e117342b9e651d6ab5048fd549fb38093e21fd369e1c6e630fbe9d24 + +handshake=Noise_X_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548cccfba3094925ef50f41bb45d6e69936ad15fcba0c3479a46afb577d3459497a2b1b0c7f3c1107df1feeb7d2e340fd886d56a823c51b82cc9bbef609fcb249aa5dc6bfae8b03f645e11 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=2e04749040fde470ab93dda9ca2d7dc69896d0c564d0898755a09830735187 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=11ca4c30bd3b563c23f5a5ae83844d038b1ae8ac7ed4e7e788ad9cdfb56c39 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546a25d60fc3551b45b422660fc5330a9a9a211a4c015192a4cb45f9e2736c0e75f6af9abf7f31d35f75534eac6e1181ed61bd13d0da02b4849bac05762a942acd1f8196a3e9abd1804c1a +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=6f84a4ede3160b3464efec0b87051e3555832871ffb6b3f3549461507068cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=83ac689c3ac344c2b7fbbaacc8d655c9ff0a1a89458b12ceb4510e80b5f9da + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA256 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625433e53e3ef1c689e4802f9453dd73c9402aa8072a810f934f7a466d2ede7d8ca79f78c9011a748444af8a1d2ac4beffd3425ca4e756799dee05a737edccc12925ee623b4305c3410a3753 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=131094feaa8cbacb6c348050711162cf8d44b13e8de882c98410e7d3981d51 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=15fcd4e117342b9e651d6ab5048fd549fb38093e21fd369e1c6e630fbe9d24 + +handshake=Noise_NN_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f8006a097c5b557f4464c7b27dbd8e35 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=984f97fa7c1125c40ac0c3bb124e9a60fe179997c677873ab695f7b19ac262 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6826eeac32a5efc75cb0fcbdc9833c4fdcbad4923c77064f83ee7dfbdc288f + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254974676d1695ef76c90de21fd792bcbbf +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664295530903147b2ef9fa23131d315e89 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0613a33b46a7b58b27aee0341bb301c9ab995009b4cc5184fbb5a8cf7be53d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cab31d679356097d8d190df5c068dee6e2ba4e4c275fd81e25c019bf65f6d + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d74b5809b1cc7872a9b81f4042b3e795 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660541a69fa4c2c12112d7506b314c7c3f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abf9e02663066047949fc2b5618d5ac5e2c078cdb011b7ed7a8f97aa4436b0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d85667b02a4a35a2c701afbca632f1c94741b2fc3345220d6b74af80134ca9 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aaf57bcc7f1092854b42b9d236a4c004 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466159739894d9652a3509deb14b3a10299 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be2eff0ceb13ed28f46bd59b64b8acb937ada777ee557f6147111e9fbc5d25 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79c9684daee2cdbf5117ccd166e2da4ef6bfd9c7babc9ab75e5d3665518cbd + +handshake=Noise_NN_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466114578170ac333f0a403ad4d13e744e5040f7f860764f72ede92 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=984f97fa7c1125c40ac0c3bb124e9a60fe179997c677873ab695f7b19ac262 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6826eeac32a5efc75cb0fcbdc9833c4fdcbad4923c77064f83ee7dfbdc288f + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c2a9acfae038fa688b36a860ce3cab6de204e5286be35d42db1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633d99a5f182be11e1105b85168c151b4b5551d5ef3ade5e59ce2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0613a33b46a7b58b27aee0341bb301c9ab995009b4cc5184fbb5a8cf7be53d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cab31d679356097d8d190df5c068dee6e2ba4e4c275fd81e25c019bf65f6d + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541686d22f6e5298997dc0c473114ab1dc6e02dc2355872726df0e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466402b1ffabe29fc69e1daad0ecafe3a6282d4ad0aeb7ee6625e2c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abf9e02663066047949fc2b5618d5ac5e2c078cdb011b7ed7a8f97aa4436b0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d85667b02a4a35a2c701afbca632f1c94741b2fc3345220d6b74af80134ca9 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b3a376dcfce9e9147a0616a720fd3172ecb619f17eccdc9005ab +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846693b56fc7a048915c8251b5382ce54df64c1d362e477150d6a07b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be2eff0ceb13ed28f46bd59b64b8acb937ada777ee557f6147111e9fbc5d25 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79c9684daee2cdbf5117ccd166e2da4ef6bfd9c7babc9ab75e5d3665518cbd + +handshake=Noise_NN_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667cc7b2813fbd918f730af3e151d18ebc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=984f97fa7c1125c40ac0c3bb124e9a60fe179997c677873ab695f7b19ac262 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6826eeac32a5efc75cb0fcbdc9833c4fdcbad4923c77064f83ee7dfbdc288f + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c6e9ea5266f8fe353cd01f932b2a7804 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dbb235f1ab9dc24f035f317418338415 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0613a33b46a7b58b27aee0341bb301c9ab995009b4cc5184fbb5a8cf7be53d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cab31d679356097d8d190df5c068dee6e2ba4e4c275fd81e25c019bf65f6d + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ee047aa2f9f98eabb4e2e09bb1970c42 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466241ec162167033e63b0abca7874e3355 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abf9e02663066047949fc2b5618d5ac5e2c078cdb011b7ed7a8f97aa4436b0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d85667b02a4a35a2c701afbca632f1c94741b2fc3345220d6b74af80134ca9 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625451990afd47d5cff7607df29d7e08b05c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663bf1d1f0f5c435b3018b3c8ba0a625c1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be2eff0ceb13ed28f46bd59b64b8acb937ada777ee557f6147111e9fbc5d25 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79c9684daee2cdbf5117ccd166e2da4ef6bfd9c7babc9ab75e5d3665518cbd + +handshake=Noise_NN_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466114578170ac333f0a4036ded1f916a042a8b557f6b850f608d5f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=984f97fa7c1125c40ac0c3bb124e9a60fe179997c677873ab695f7b19ac262 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6826eeac32a5efc75cb0fcbdc9833c4fdcbad4923c77064f83ee7dfbdc288f + +handshake=Noise_NNpsk0_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c2a9acfae038fa688b361ef2dab5318ec6e764eeaeb60312d9b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633d99a5f182be11e11056d6f69deb26bfc780001cca9428c875d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0613a33b46a7b58b27aee0341bb301c9ab995009b4cc5184fbb5a8cf7be53d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5cab31d679356097d8d190df5c068dee6e2ba4e4c275fd81e25c019bf65f6d + +handshake=Noise_NNpsk1_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541686d22f6e5298997dc08d43269f7d5bae51225e05e672adaef1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466402b1ffabe29fc69e1da4133d3c9e013bc17c3e78f908ce4c654 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=abf9e02663066047949fc2b5618d5ac5e2c078cdb011b7ed7a8f97aa4436b0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d85667b02a4a35a2c701afbca632f1c94741b2fc3345220d6b74af80134ca9 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_SHA512 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b3a376dcfce9e9147a06727bb95b42b46c2791a6e07c1824a5af +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846693b56fc7a048915c8251fd399101582872eab051fbe3bc3ef39c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be2eff0ceb13ed28f46bd59b64b8acb937ada777ee557f6147111e9fbc5d25 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79c9684daee2cdbf5117ccd166e2da4ef6bfd9c7babc9ab75e5d3665518cbd + +handshake=Noise_KN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a05b47c8265d4ab0222de8450c1a67fc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f3c9fbbd304f284cbf067f089801a6cbdefa9ec68ce8a186b3ec6198eff1b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e4508095fd5fa73c415d881b7b7b5519a522c358eaee583f65379a82746c72 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a605358c47ddb81dd2a4c82b4c275e2d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ce6754e492246db11d29b0ebfd513bc4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=216cfab041942d740699e1d9b13b70be15efd1842776ae8bbbcff63e5ab6f3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f390f1ed96ab34cc1ad8e419f44afb39d6c152556d04fd8285e16480f4542 + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541786642ee04970b496f2d5463b0aabb0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846647a2b31a6688efaff36c8fa66ee16eac +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d71742981c22266f55a203db331274afe42f2fcbb53cd54743f0eb4b09112b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=896562cb84ade13be47e2cd28b0244f4006df84781d971b8ddd0383395adc0 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625490b21825eee9e45abc6ff262aca6e634 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846684e4d22747f1a8b988b94cb283b34885 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bfe4815658302d4f593705a806e1102e3a2a0a36dc847aa612586a035edaa3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=dc23a01b665cafc7c1baafeda8e705ee9e0f8a0f1f4c9b89814cb747274c08 + +handshake=Noise_KN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ac57ebc5143d3134c5674a209111f914f49e33f0c29b6e232822 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f3c9fbbd304f284cbf067f089801a6cbdefa9ec68ce8a186b3ec6198eff1b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e4508095fd5fa73c415d881b7b7b5519a522c358eaee583f65379a82746c72 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543cd51e47fb9aa475e18e123b157d4e9ee222e358cc22e19916a3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846647dfb3375c1e7beabafacf5cd875d25dbfbe5d5fd5762503b6cc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=216cfab041942d740699e1d9b13b70be15efd1842776ae8bbbcff63e5ab6f3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f390f1ed96ab34cc1ad8e419f44afb39d6c152556d04fd8285e16480f4542 + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543fb5766cc4bc875a8c94708eed1c40bad1376f555482ee213c4c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eeb430d11573629ee9f48689ee97e44a23404b52878c01f8129d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d71742981c22266f55a203db331274afe42f2fcbb53cd54743f0eb4b09112b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=896562cb84ade13be47e2cd28b0244f4006df84781d971b8ddd0383395adc0 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254033b7a5813ca73b834666f8c07644ac14f8bccffe995d2ded587 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c95ee12179a4d001f6e0beb00425609cf2cd7a7f17766a623f53 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bfe4815658302d4f593705a806e1102e3a2a0a36dc847aa612586a035edaa3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=dc23a01b665cafc7c1baafeda8e705ee9e0f8a0f1f4c9b89814cb747274c08 + +handshake=Noise_KN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669d58ab3ea3c810e67a9e0bc3f8b31cad +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f3c9fbbd304f284cbf067f089801a6cbdefa9ec68ce8a186b3ec6198eff1b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e4508095fd5fa73c415d881b7b7b5519a522c358eaee583f65379a82746c72 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254028d29d14a56c53b7db28781e4b8e0ec +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669ce4da10e934ba7a166a6518c4d9fd18 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=216cfab041942d740699e1d9b13b70be15efd1842776ae8bbbcff63e5ab6f3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f390f1ed96ab34cc1ad8e419f44afb39d6c152556d04fd8285e16480f4542 + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625413e83f08edd08acd29015742d043f59b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cab3cb9abaebcd0b566d2d3fdc38039a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d71742981c22266f55a203db331274afe42f2fcbb53cd54743f0eb4b09112b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=896562cb84ade13be47e2cd28b0244f4006df84781d971b8ddd0383395adc0 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625493a48efb4ac89aafa2eba5be4722b098 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846639b3e3cb2a7a8813f232329758728863 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bfe4815658302d4f593705a806e1102e3a2a0a36dc847aa612586a035edaa3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=dc23a01b665cafc7c1baafeda8e705ee9e0f8a0f1f4c9b89814cb747274c08 + +handshake=Noise_KN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ac57ebc5143d3134c567adc45d5a0da7645b723d3653a951aa1a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7f3c9fbbd304f284cbf067f089801a6cbdefa9ec68ce8a186b3ec6198eff1b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e4508095fd5fa73c415d881b7b7b5519a522c358eaee583f65379a82746c72 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543cd51e47fb9aa475e18e4b5ca06c89b89d86120b3a6925871f0b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846647dfb3375c1e7beabafaaf3082b2bafc8456a2751912500c2a3a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=216cfab041942d740699e1d9b13b70be15efd1842776ae8bbbcff63e5ab6f3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f390f1ed96ab34cc1ad8e419f44afb39d6c152556d04fd8285e16480f4542 + +handshake=Noise_KNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543fb5766cc4bc875a8c94660ba2bf08b944693946e4d1842d6003 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466eeb430d11573629ee9f4be8a75aae8683f5d5e87a90e4581f68e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d71742981c22266f55a203db331274afe42f2fcbb53cd54743f0eb4b09112b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=896562cb84ade13be47e2cd28b0244f4006df84781d971b8ddd0383395adc0 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254033b7a5813ca73b83466231a71a631b5aaa173c4529f435385b7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c95ee12179a4d001f6e0b2073ec8b7c064daad044fdc8e3f9f2a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=bfe4815658302d4f593705a806e1102e3a2a0a36dc847aa612586a035edaa3 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=dc23a01b665cafc7c1baafeda8e705ee9e0f8a0f1f4c9b89814cb747274c08 + +handshake=Noise_NK_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541ae9c9a6658068e796f1609d0738cf24 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666a553cbfe29b06c54b679290a63b357e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e81871e9c00f0153758cddbae509bd548b0f5a02eab4751107842ef6b6a93c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=16cbc8684ec246d78a72c6421aa737ed4441ac751cdd4510617decffe89dfd + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254098cdd7308257dd69233ab7d725ee8bc +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668edb3682137234dad14a8b4c8866e03d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7cb6cbbbddfefdc4d030ab94ab2aab13422ef4d87e054a08bb10da446c6f36 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e3926ab002f3c5051150d49e11388040a8397644b461aed00fad63e8023241 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cbd6c6755faedda9da18ea3a14dbb128 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664c48eb806966bdd24e98fe421b3d4815 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1193e531aed0c1f9c475668bc5420beb3ee15f3520931d4a283185763289fa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d4b9ff958655454654452cfc613b0b9a7fd7dac8aae5f1f0382edba43b0d1a + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625486bf3bfeb6861b365528620b68992d7b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668acd99b4cbc7ce0c14ff2be16afc02bf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=65fd72393fd5065a54fa40313eaf8b7a052631aaf3f7368622f909aff8f4e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=28de903b3a3f50fd29d23549b726ddeb4c16f7db17c1757b4dd8d54ecfd8a2 + +handshake=Noise_NK_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625490f8f004794122bca779d9bedcc39b7bfb88883f6a56029320aa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e93b0314d9d7741d4e27466c0dd7656cf06185f352ffe422a67d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e81871e9c00f0153758cddbae509bd548b0f5a02eab4751107842ef6b6a93c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=16cbc8684ec246d78a72c6421aa737ed4441ac751cdd4510617decffe89dfd + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254686ba4c18195ad7d41e9992316453c355d139541985ab5a3966f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d153be7723be9f8b575546cf935485ad9ab67635c3570d782a7a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7cb6cbbbddfefdc4d030ab94ab2aab13422ef4d87e054a08bb10da446c6f36 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e3926ab002f3c5051150d49e11388040a8397644b461aed00fad63e8023241 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254210d5de7949ae573f825864efec44aec7e75233f354d162612d0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c58fd6fcb9ef1553a6b2f2800aeb72958e3cc8bbb74a7d21b9b2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1193e531aed0c1f9c475668bc5420beb3ee15f3520931d4a283185763289fa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d4b9ff958655454654452cfc613b0b9a7fd7dac8aae5f1f0382edba43b0d1a + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c009a07ab83cf19c6e7f8cdce6b7810b8fd94271ebe94286d91 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ef6e6049aca18b319ec85d018f1abc9f9b886f0291177f84af35 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=65fd72393fd5065a54fa40313eaf8b7a052631aaf3f7368622f909aff8f4e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=28de903b3a3f50fd29d23549b726ddeb4c16f7db17c1757b4dd8d54ecfd8a2 + +handshake=Noise_NK_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e84c76e8c7b65cb632b4b7e044462340 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665e44b83033cf4b6c0632338348ba3010 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e81871e9c00f0153758cddbae509bd548b0f5a02eab4751107842ef6b6a93c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=16cbc8684ec246d78a72c6421aa737ed4441ac751cdd4510617decffe89dfd + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254078dc0cb4f3e257498b0326b749ed738 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846611a2822f0742f8b8d78d49e4826d4768 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7cb6cbbbddfefdc4d030ab94ab2aab13422ef4d87e054a08bb10da446c6f36 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e3926ab002f3c5051150d49e11388040a8397644b461aed00fad63e8023241 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e2f9cfc860db48368e8e7b088ac14ac9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663518375638c3a6f8b52d108e2eca0c65 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1193e531aed0c1f9c475668bc5420beb3ee15f3520931d4a283185763289fa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d4b9ff958655454654452cfc613b0b9a7fd7dac8aae5f1f0382edba43b0d1a + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625492ab9d1af417323e2bc1b5d5ab5a9795 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846626b056d1f03521f4218c4e423a14182b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=65fd72393fd5065a54fa40313eaf8b7a052631aaf3f7368622f909aff8f4e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=28de903b3a3f50fd29d23549b726ddeb4c16f7db17c1757b4dd8d54ecfd8a2 + +handshake=Noise_NK_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625490f8f004794122bca7798750ae0cdabd48361711c1194a3a80ac +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e93b0314d9d7741d4e27e87d0ce6e3fe0f2b2b1c073a577dde57 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e81871e9c00f0153758cddbae509bd548b0f5a02eab4751107842ef6b6a93c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=16cbc8684ec246d78a72c6421aa737ed4441ac751cdd4510617decffe89dfd + +handshake=Noise_NKpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254686ba4c18195ad7d41e9353c11fdf8f2db2246391ecb8dd0fdf1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d153be7723be9f8b575534d2a1f435076015a844d771ca0cf06b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7cb6cbbbddfefdc4d030ab94ab2aab13422ef4d87e054a08bb10da446c6f36 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e3926ab002f3c5051150d49e11388040a8397644b461aed00fad63e8023241 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254210d5de7949ae573f825ac5a5aebcfe6558f9de711f803dca24a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c58fd6fcb9ef1553a6b208182eca4927db5b6ebede70e11c926f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1193e531aed0c1f9c475668bc5420beb3ee15f3520931d4a283185763289fa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d4b9ff958655454654452cfc613b0b9a7fd7dac8aae5f1f0382edba43b0d1a + +handshake=Noise_NKpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c009a07ab83cf19c6e7468cbd4dd5693d61810307b3a1037ca2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ef6e6049aca18b319ec8175c93ded5a053ed7324261bb7944cee +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=65fd72393fd5065a54fa40313eaf8b7a052631aaf3f7368622f909aff8f4e8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=28de903b3a3f50fd29d23549b726ddeb4c16f7db17c1757b4dd8d54ecfd8a2 + +handshake=Noise_KK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625422ed6d5d012d0c7b8b7c91b303b2eeaa +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667db7a98eb9c50939d9d424becba2cfe4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0dc5775f180ebbca24ba2dbedf7df763974789fffe201a7158f92c61c21e56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=94573c8b800345c65607ec7bd2244bcd871c8e73247b6835ad35334257460c + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625435c738ecdc74a3da8ba56685cbda15fb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e6f50e396f3bfa2a91db76cf3550b57a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cb7d802310849d2cbcb2bf628d5b5be8694cff1cd9d9fe4d88270315550664 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8c51f3b2a7bdef2910114236378b9d97d5b0a5054f3e6e0b93d9ba1439a314 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542aa38a5f7583c960333ffdb92f005d72 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b3a625b74b537cdd5581ca17b2d20c91 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=14e6e930733e777341e6bb7ec522f24f7aff05b125bf49d45b5150d2c8eee8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39a6c784e7e5f91d33ba6200a4bfb333e9e5d5974e89b8c92f7cca58641e98 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ac287025515a5ec183f396ac7626bceb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466680cff1a53276ab7f03431d5fe2ddf49 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1ee2a40d2d547aa1ecff9085d876d61bef6d5faa010db3e983313e28a84176 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=022620f1e6e067f7af42f407df7b37bfe24da7a7d79d91f3d3278bee00809f + +handshake=Noise_KK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625439201e9eaf437b4be19b1452073cf37e9fad03973780eb051f13 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669d683ff6a052688a4bf54d599e036fb4cf5d8c4fe35628270a9a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0dc5775f180ebbca24ba2dbedf7df763974789fffe201a7158f92c61c21e56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=94573c8b800345c65607ec7bd2244bcd871c8e73247b6835ad35334257460c + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7d83c70d4f86e56a84f48e3f71d9451d09c606773101e89a3fa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662d99936cb48465009334c1afddb55f62072449be590183a496b7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cb7d802310849d2cbcb2bf628d5b5be8694cff1cd9d9fe4d88270315550664 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8c51f3b2a7bdef2910114236378b9d97d5b0a5054f3e6e0b93d9ba1439a314 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625428bddcbf220404e1f3344e37fae6b2b658565e8322fde73aae4a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b6be75c4a8160a18b20eafa7a5919dbc8dab95aa27d4604038ec +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=14e6e930733e777341e6bb7ec522f24f7aff05b125bf49d45b5150d2c8eee8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39a6c784e7e5f91d33ba6200a4bfb333e9e5d5974e89b8c92f7cca58641e98 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dcbb401e89f43c8af94bbdf465fb33a6d47244a2b418f7946bf4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466766cf40c486fe6860ad473d82a2500671ef59ee6cd2096af1427 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1ee2a40d2d547aa1ecff9085d876d61bef6d5faa010db3e983313e28a84176 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=022620f1e6e067f7af42f407df7b37bfe24da7a7d79d91f3d3278bee00809f + +handshake=Noise_KK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546100613cdbb5fe7b350dc52dba01d51c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846613f7bc06352a6a111cf882cbb90fb733 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0dc5775f180ebbca24ba2dbedf7df763974789fffe201a7158f92c61c21e56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=94573c8b800345c65607ec7bd2244bcd871c8e73247b6835ad35334257460c + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254186a15c02343bc4dd83d048fa63f5304 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665e19c67762e245b10dd4f42441152693 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cb7d802310849d2cbcb2bf628d5b5be8694cff1cd9d9fe4d88270315550664 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8c51f3b2a7bdef2910114236378b9d97d5b0a5054f3e6e0b93d9ba1439a314 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aafd5f671a619fdf23e78fdde0739a99 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846608923bb663020fcbd98f46f96b19838e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=14e6e930733e777341e6bb7ec522f24f7aff05b125bf49d45b5150d2c8eee8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39a6c784e7e5f91d33ba6200a4bfb333e9e5d5974e89b8c92f7cca58641e98 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b612c908afa3994b259f7bbe6f61d48b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660200b1bebc05ec930091302b462ee495 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1ee2a40d2d547aa1ecff9085d876d61bef6d5faa010db3e983313e28a84176 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=022620f1e6e067f7af42f407df7b37bfe24da7a7d79d91f3d3278bee00809f + +handshake=Noise_KK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625439201e9eaf437b4be19be0e1fd46345e956541b7a79bedfc0a44 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669d683ff6a052688a4bf5d08f5e907b60839eaf900ab19faff7b3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0dc5775f180ebbca24ba2dbedf7df763974789fffe201a7158f92c61c21e56 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=94573c8b800345c65607ec7bd2244bcd871c8e73247b6835ad35334257460c + +handshake=Noise_KKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7d83c70d4f86e56a84f27bf60c3bd52c62f0ee0b8dd9fc54d94 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662d99936cb484650093346699bf1d8c0806c839532d2d8ab258d1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=cb7d802310849d2cbcb2bf628d5b5be8694cff1cd9d9fe4d88270315550664 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8c51f3b2a7bdef2910114236378b9d97d5b0a5054f3e6e0b93d9ba1439a314 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625428bddcbf220404e1f3342045d5a40b989d199aea6a10b95443af +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b6be75c4a8160a18b20ed33cc111a2da1ba4ad020106b496a765 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=14e6e930733e777341e6bb7ec522f24f7aff05b125bf49d45b5150d2c8eee8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39a6c784e7e5f91d33ba6200a4bfb333e9e5d5974e89b8c92f7cca58641e98 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dcbb401e89f43c8af94bc27709f8e7ea9d2baeacbe96f51e4d92 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466766cf40c486fe6860ad4ed44c066c8102966ab34d3e295b04ebe +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1ee2a40d2d547aa1ecff9085d876d61bef6d5faa010db3e983313e28a84176 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=022620f1e6e067f7af42f407df7b37bfe24da7a7d79d91f3d3278bee00809f + +handshake=Noise_NX_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846646b94b876aef590a75654b6ad3759d4a2b887f24780015b9f52dce3318747d1421273ee37fab11ec0e19b97e016019eba398fd0234f4f397c37869498760e015 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b5d17fa3d357b71df323fb36fe9468c8b8231d52687d3ab34e943d5176559f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9604b7d4aeb5d2d669004203e5ea36a496185d60aa484d843de5ce6504fcf2 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625486484f9dc39cfcb069ca0a6b4fb53898 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466073c7b8893efddc83a6550268f1f2b58b810514f8ceb8839db90f8bd9c2d88e8839bdfbf351f047acabb381fb6432cc1098d42a95e5226dd40e64b67fa0d021f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b29d746b8d07a50fb43cde476703b870b5d9ef75e760dbb38548ff5449b74b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=575261f1aece9f5960ed5e51ecafb480adef5c1b681509cc73270b63b0cc58 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9f6b397b7e8f8dc1bc7e73b0c61286f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466df854f551297c8c948841769640157bb0a68e959679f8956f3f078956be2c39c8de3427a96c0db5628e54857e7e316efc2d4ea29d8ecd50c31bd439f99a75736 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d1dcb9b1e4dbba2386624a124bb1539e391e890c463a8940127ae765eb6aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6334f69a2c9bcf6c7c1aff16f653da4b241ce641ebb859f456923670bd0c35 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547bc9eeadef9d1cd0dbc4a06e004c06b6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e758b813c78910a7246ba02fa2bf78f1f91df195e41d33fd94c03e51aa35750983a79f279c5845431d6ec30e9122d07d1b1a2f219ef8ff8fe043ca9e6e8e0f2e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8e98a23dc6de8edee0529f80f7d14be0774f42c6d90fbc56d0d5d27b9c207 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9de92b1e88a0cb7794854160cae0f948c366287194e571c8e0922554cb78bb + +handshake=Noise_NX_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846646b94b876aef590a75654b6ad3759d4a2b887f24780015b9f52dce3318747d14fe963b90ba2e278d62c50e22832a691765f20777ea751a010257b1616a6de3043e332e8e891e5d4afdeb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b5d17fa3d357b71df323fb36fe9468c8b8231d52687d3ab34e943d5176559f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9604b7d4aeb5d2d669004203e5ea36a496185d60aa484d843de5ce6504fcf2 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541b57ff52600948c125f4a5c4d387d7cef809d8036fd40ed2e108 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466073c7b8893efddc83a6550268f1f2b58b810514f8ceb8839db90f8bd9c2d88e8b4a4972b01bd3a29057bd6f1e9e5b90570f6cb66d26bb6164e544dc248a26347b3c7f87d473ee01ba434 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b29d746b8d07a50fb43cde476703b870b5d9ef75e760dbb38548ff5449b74b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=575261f1aece9f5960ed5e51ecafb480adef5c1b681509cc73270b63b0cc58 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f512badfe5247731af42e55b1324f361c190926302ffdbc1eef7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466df854f551297c8c948841769640157bb0a68e959679f8956f3f078956be2c39c940b3d894e4d2f72db33c47e6355d445f4b4456e5d2ea966b4bf8bcdb5dfe2c29aa68488b3f82d5526d7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d1dcb9b1e4dbba2386624a124bb1539e391e890c463a8940127ae765eb6aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6334f69a2c9bcf6c7c1aff16f653da4b241ce641ebb859f456923670bd0c35 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547664a776a6da240a65ab7b2c75ed4cd21f507d1d609e65f11a74 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e758b813c78910a7246ba02fa2bf78f1f91df195e41d33fd94c03e51aa357509868f2beb823e19c97840ee2171198d4c02d416c7ca47cee015daa374cc9074a2c53a48a516d5f467572b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8e98a23dc6de8edee0529f80f7d14be0774f42c6d90fbc56d0d5d27b9c207 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9de92b1e88a0cb7794854160cae0f948c366287194e571c8e0922554cb78bb + +handshake=Noise_NX_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846646b94b876aef590a75654b6ad3759d4a2b887f24780015b9f52dce3318747d1480c897964b162ef9638256026c093979aa00d4334a90f1ec65206e5102364b7e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b5d17fa3d357b71df323fb36fe9468c8b8231d52687d3ab34e943d5176559f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9604b7d4aeb5d2d669004203e5ea36a496185d60aa484d843de5ce6504fcf2 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548cc277e07714f923bddfbe134b7cdcb7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466073c7b8893efddc83a6550268f1f2b58b810514f8ceb8839db90f8bd9c2d88e89d03c776cd7ec28d70e84e6c387ef70b0e46454c8b950550860815a2ee213171 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b29d746b8d07a50fb43cde476703b870b5d9ef75e760dbb38548ff5449b74b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=575261f1aece9f5960ed5e51ecafb480adef5c1b681509cc73270b63b0cc58 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aabe871c6705c33c5e6812e239569c08 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466df854f551297c8c948841769640157bb0a68e959679f8956f3f078956be2c39cd24b6200d5fbe33debec8cbb3a4a266b69ef965c80b1a345caac03508e6a462f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d1dcb9b1e4dbba2386624a124bb1539e391e890c463a8940127ae765eb6aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6334f69a2c9bcf6c7c1aff16f653da4b241ce641ebb859f456923670bd0c35 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545fb3c95fcffb1e687a983bf52c73e46e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e758b813c78910a7246ba02fa2bf78f1f91df195e41d33fd94c03e51aa3575090102a531c19850c4c0a6e9e7831a97553a0c85ba8f73d9e895f7af081c5a2d20 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8e98a23dc6de8edee0529f80f7d14be0774f42c6d90fbc56d0d5d27b9c207 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9de92b1e88a0cb7794854160cae0f948c366287194e571c8e0922554cb78bb + +handshake=Noise_NX_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846646b94b876aef590a75654b6ad3759d4a2b887f24780015b9f52dce3318747d14a02d1af836b904cdc2331de53846c36b65f20777ea751a010257af5106dbf27395fbb55e705de1c21894 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b5d17fa3d357b71df323fb36fe9468c8b8231d52687d3ab34e943d5176559f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9604b7d4aeb5d2d669004203e5ea36a496185d60aa484d843de5ce6504fcf2 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541b57ff52600948c125f44b02653596239ee0c152247266ab71ff +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466073c7b8893efddc83a6550268f1f2b58b810514f8ceb8839db90f8bd9c2d88e85de4226713c8a68e15e259379d0bf3c870f6cb66d26bb6164e54d4475c4f7b4f79f00db1d34e4897233a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b29d746b8d07a50fb43cde476703b870b5d9ef75e760dbb38548ff5449b74b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=575261f1aece9f5960ed5e51ecafb480adef5c1b681509cc73270b63b0cc58 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f512badfe5247731af4236af5558ff1540b60219e82ed4fee868 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466df854f551297c8c948841769640157bb0a68e959679f8956f3f078956be2c39c385c53c43c3ffc2b5bbea33db14dbec3f4b4456e5d2ea966b4bfb56f3cb874d5c7b23b76b52ec0f9ac32 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d1dcb9b1e4dbba2386624a124bb1539e391e890c463a8940127ae765eb6aee +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6334f69a2c9bcf6c7c1aff16f653da4b241ce641ebb859f456923670bd0c35 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547664a776a6da240a65aba904f90d1eaa5f44454c7cb850438789 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e758b813c78910a7246ba02fa2bf78f1f91df195e41d33fd94c03e51aa35750948e563125f88f23f662a24cab0ae857302d416c7ca47cee015dad0910b515661e0062e9f13e5bff3b05e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e8e98a23dc6de8edee0529f80f7d14be0774f42c6d90fbc56d0d5d27b9c207 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=9de92b1e88a0cb7794854160cae0f948c366287194e571c8e0922554cb78bb + +handshake=Noise_KX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846698119b787fffa4ac2c31f25455c130cf4de25f7384a93535288b79d7da78ad57dcedde22e3c3bfbdd4123468b03f56acebb709800aaf11ff0a383891f7e13e7f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=645d87cb21d68205c5d1d5ace656933772726dc15677fa66ecbb0d9e7c4a76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f5021dc910cb1c6c6c1789bc0e1383e616b8a0706ce7e8c9de0038b94c7ae3 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625420c520dc8393601629a9a4b0442dde86 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ff370f61dd7f82942851279f7749a086d1bf8d2975f632a8917f266aeb7a015ed99da110b6f09d00c39aad859dbca8df6235fbb88c5ef51a8e680b281421f61c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c7b22671faef802e2d77369ee735381ed398d69c460aaacf316284f3ef9aad +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=af44c5d5da5673e25de13a9f767e492ee14e50d7866252021d594b50de5482 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254171daeee62ba0080fa7246ee5640d14a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c234402484dec5e7c50aa677ecc860e1006ed5575482ccc537336b0c0810c9761e8591300938fc3dd8280a499b8effe7b0f575edc0525bb334884f1c5a7f8a5d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=522cff6137e48e907204736ed64baeff2a255653a1f54cfc85c1fcb89a38e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a0e5114517474c8aea753cd6286906b640d6504e446cc65840f91c2ae4ff2d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437cad4dcdeaad9e6c772f632ef0f0219 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fe9957e4a8cf74cd95f22436f4cf0e40492e620ecef46cd0927053bea29b9fc3a446d8a8476c205ad279277e78b42fa40ab44a17da0ea17c7bdc385c52156d3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a8c3c1697a1444f8aaf5c1f30f8f47fe5f2edc883495d0a5fa03b5be468105 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=272a63fdf5bc0dac82c112f669218e7c0f49708ce1c24fcc16eaec673c8ffb + +handshake=Noise_KX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846698119b787fffa4ac2c31f25455c130cf4de25f7384a93535288b79d7da78ad576c29eb2fc4fc0373ed8cf04ebe98c88763f453e22f5bf4fea56930d1b112a72635a554fb65faa2ac41b7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=645d87cb21d68205c5d1d5ace656933772726dc15677fa66ecbb0d9e7c4a76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f5021dc910cb1c6c6c1789bc0e1383e616b8a0706ce7e8c9de0038b94c7ae3 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548c42693ab9b2b64f32e396a1c5c1cf40666e2447991b4301219a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ff370f61dd7f82942851279f7749a086d1bf8d2975f632a8917f266aeb7a015ed112c9698130c8f77715bb1606ee158a1bf0561b47f1fa3358fd7f873c8fb725b873f32a3a2b74818ad5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c7b22671faef802e2d77369ee735381ed398d69c460aaacf316284f3ef9aad +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=af44c5d5da5673e25de13a9f767e492ee14e50d7866252021d594b50de5482 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625429641c04894b9a11f27d044ce0cd6700c86d74b6c6b2e0a36631 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c234402484dec5e7c50aa677ecc860e1006ed5575482ccc537336b0c0810c97614f780867dcfa660718c9445ddb0b18adb74ab7d4bb6da9bebc94b680fa2005464fb98609980ad19a71b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=522cff6137e48e907204736ed64baeff2a255653a1f54cfc85c1fcb89a38e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a0e5114517474c8aea753cd6286906b640d6504e446cc65840f91c2ae4ff2d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540a6409e4470fb6ff0e4814ec0d6311dcbdebc35784830d1fbed8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fe9957e4a8cf74cd95f22436f4cf0e40492e620ecef46cd0927053bea29b9fcfdc326f3f799fa284adde53c57a64e92a31ea878b11cc8a07a211d9d1a425caf0a49fb0a54759b386248 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a8c3c1697a1444f8aaf5c1f30f8f47fe5f2edc883495d0a5fa03b5be468105 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=272a63fdf5bc0dac82c112f669218e7c0f49708ce1c24fcc16eaec673c8ffb + +handshake=Noise_KX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846698119b787fffa4ac2c31f25455c130cf4de25f7384a93535288b79d7da78ad57be7743fad001edc79215121d52d586527894eb7516dbd70d353c8174849e3fb7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=645d87cb21d68205c5d1d5ace656933772726dc15677fa66ecbb0d9e7c4a76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f5021dc910cb1c6c6c1789bc0e1383e616b8a0706ce7e8c9de0038b94c7ae3 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447b7249372647d750def52e1c5e505de +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ff370f61dd7f82942851279f7749a086d1bf8d2975f632a8917f266aeb7a015e37746122f2158189601b656f82a28272f471a98dd3e9cb92f15dcb31b2d61afe +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c7b22671faef802e2d77369ee735381ed398d69c460aaacf316284f3ef9aad +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=af44c5d5da5673e25de13a9f767e492ee14e50d7866252021d594b50de5482 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549a46b6cc19675c81a7c17e59ae2fbb77 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c234402484dec5e7c50aa677ecc860e1006ed5575482ccc537336b0c0810c976a3e88fa64138fea30ee9b5dfb5f7edf054d75d4cb3788e22dc531cf95b5e2f48 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=522cff6137e48e907204736ed64baeff2a255653a1f54cfc85c1fcb89a38e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a0e5114517474c8aea753cd6286906b640d6504e446cc65840f91c2ae4ff2d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419b10036434a604f7ad315181f250980 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fe9957e4a8cf74cd95f22436f4cf0e40492e620ecef46cd0927053bea29b9fc64f37ec0795f68ed37302d9790f1282a4e9570c27bc6fba150347584f533aa77 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a8c3c1697a1444f8aaf5c1f30f8f47fe5f2edc883495d0a5fa03b5be468105 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=272a63fdf5bc0dac82c112f669218e7c0f49708ce1c24fcc16eaec673c8ffb + +handshake=Noise_KX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846698119b787fffa4ac2c31f25455c130cf4de25f7384a93535288b79d7da78ad57d1ec426cdbfc40cc5b485727b8e8243463f453e22f5bf4fea56964b42c087e66e0d151039f27af53d4fd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=645d87cb21d68205c5d1d5ace656933772726dc15677fa66ecbb0d9e7c4a76 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f5021dc910cb1c6c6c1789bc0e1383e616b8a0706ce7e8c9de0038b94c7ae3 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548c42693ab9b2b64f32e3c4cfe206c4b91682f9f8f6936fc9afbe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ff370f61dd7f82942851279f7749a086d1bf8d2975f632a8917f266aeb7a015ee7c5ca712002095e484838ae25fd75461bf0561b47f1fa3358fdf8e83366ddb4923b44739185cea05565 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c7b22671faef802e2d77369ee735381ed398d69c460aaacf316284f3ef9aad +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=af44c5d5da5673e25de13a9f767e492ee14e50d7866252021d594b50de5482 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625429641c04894b9a11f27da81cd77c9a037dcdb91e7d38713655de +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c234402484dec5e7c50aa677ecc860e1006ed5575482ccc537336b0c0810c9761e984ed70366c1429556ad81e7ffc621db74ab7d4bb6da9bebc94678f2c759019dd38f17f4672db5fe6b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=522cff6137e48e907204736ed64baeff2a255653a1f54cfc85c1fcb89a38e7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a0e5114517474c8aea753cd6286906b640d6504e446cc65840f91c2ae4ff2d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540a6409e4470fb6ff0e4867ac27fa94e39def5fb9cff692b08053 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fe9957e4a8cf74cd95f22436f4cf0e40492e620ecef46cd0927053bea29b9fc80694fe3959f5da3630331671ddae3d5a31ea878b11cc8a07a219cbdbb73011e081a82623aefd7500ebb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a8c3c1697a1444f8aaf5c1f30f8f47fe5f2edc883495d0a5fa03b5be468105 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=272a63fdf5bc0dac82c112f669218e7c0f49708ce1c24fcc16eaec673c8ffb + +handshake=Noise_XN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846629c447f1d9897b8983f6a3622b9c68fe +msg_2_payload= +msg_2_ciphertext=037099440bbf00ed48e8e128d88e1ef2306f1b6e68f27fa225aa4b712d77baf46f0739cd1a8302353862f0a47b0e0326ba6101e1defbff83190d7a9a5d6804ef +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c818555ad9a26b3635d18f4056dc23fbb91c3d3a7a0ec77b01ad01542bccc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e55862d8ebce08d0f83f774fc665146e3de69dd2642884d8613c7a93fd698 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cb40ef0aeb7dd7bc5077878685c5d5c2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466662ed487400777ba45d66cf3440a55f0 +msg_2_payload= +msg_2_ciphertext=8d8c26c8c2048e031c6315e24093d4ad18b7efff7595b086239c24068e3db491158bca797fa3d1cd50f571d9474b70a0e8f28e47668d42c7845f1f26ca01b513 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=899e34bc0ead03fba60e56cfd11cbb3790834e6d5c23a10dfa0b93acccc900 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6e85b7d7a6c44fb89e92477ec4caf02ef9abaede5a43eb303676eb7dc4f6e9 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cedb8e556eabaa5203ac7a28c0b4e4c5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665b07ffa8c845133bf13d3121173e1bcc +msg_2_payload= +msg_2_ciphertext=77d0e47e4dbb723e616b6f24738e459ea8e98a574f6e59732204f0363e69879fa204c34f701074ac88a7230eb5bb640377590cc82ec8b0809bd3725523fbaf57 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c651eedb26764976c359cd8f3b7e6c6cf61dec2a8e9e7cdabed1e0e5ae7cde +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=caf2c606303c4d12eddf43c5bb8330e86230cb2d8bab3dcf4eadd40776acc1 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aea85d73fe6523d3273aac24fa0e5d53 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ecbcd4c6ef7f7346437007c3c8806348 +msg_2_payload= +msg_2_ciphertext=2c5a5be592acde69362c483d714504e4fb32031199e3b8e7c9052ce199b3b045c12ba87c6a67e96f8de387e729f342425dbfadf39264e46ef3e5f25f4e1f74c0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd75543aed4fbaaa884e485c7f3f7847c2dd2c5dd6c669d81399bad151b357 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=aaf79ee8c46da36c2998983b081475ce0c55c22a2c03b6f5c36c6714ac589a + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254126f87830ce7792290f4bc27fe31e18f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466db3adfc1817b0e0bc47050f0819a7466 +msg_2_payload= +msg_2_ciphertext=b009c459289fb3451ce340c21aefbeab59707c472c0b532e3758a1fdb21962b2d0a81254c169e20fbd5bdb89cfa3f70a1d1ca9b11bcaac5f3834bdf2ad356f02 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=76ec40c6107efb6f7a22addff790390d82eef906568d70ee8ad03d8bc70fe5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4d4e7a4916c6202c5c7d4cfc502fc7d26f5ad42c9a93023a07dc09e47297e7 + +handshake=Noise_XN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a14dd9325bc6f396704c351c6d783fbecc244a54327404ddafd9 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=037099440bbf00ed48e8e128d88e1ef2306f1b6e68f27fa225aa4b712d77baf4edf2cffd49eea54222e7ab2220acf3b59a894802e80e97ef1c968acf6dac24b595997fcfb560aca4ed67 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c818555ad9a26b3635d18f4056dc23fbb91c3d3a7a0ec77b01ad01542bccc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e55862d8ebce08d0f83f774fc665146e3de69dd2642884d8613c7a93fd698 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c66d55a16b9cb77895dc7098d55af8e40e8916d8d6a818367b4e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b78d0157146db12f98a9434b8402daab60240651f013edbeddbd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8d8c26c8c2048e031c6315e24093d4ad18b7efff7595b086239c24068e3db491f8dca2295ae4b6746a616e7b5ce038761ca387a1f28499c8efff252ccb4522e99e32ef4ef38e16d0a09e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=899e34bc0ead03fba60e56cfd11cbb3790834e6d5c23a10dfa0b93acccc900 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6e85b7d7a6c44fb89e92477ec4caf02ef9abaede5a43eb303676eb7dc4f6e9 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625431ae431ebbf2fffee5c4f57d02c3f9bb6b86194e99431ccb2e78 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b5554432a018960a5dde37d862e2213837997c77d9bc99d4ae00 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=77d0e47e4dbb723e616b6f24738e459ea8e98a574f6e59732204f0363e69879fe9339af66e60b3bc4ad0d76a2b361e608ad399d3f9c470db77081b15a7e8cd34345207714fc9c00567be +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c651eedb26764976c359cd8f3b7e6c6cf61dec2a8e9e7cdabed1e0e5ae7cde +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=caf2c606303c4d12eddf43c5bb8330e86230cb2d8bab3dcf4eadd40776acc1 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d0fbe4d8c565b9a59d3664c055d51254e7a5c460f2b1d79b1512 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665489a70f5e1b78b65e0e6276106d69d27c1703e5143194ab570b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2c5a5be592acde69362c483d714504e4fb32031199e3b8e7c9052ce199b3b04525aa23a3f117933aeb082d5a6afac8943f9258c2910cd02a610abd7cbb58b5134d2648a1e871a937d77e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd75543aed4fbaaa884e485c7f3f7847c2dd2c5dd6c669d81399bad151b357 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=aaf79ee8c46da36c2998983b081475ce0c55c22a2c03b6f5c36c6714ac589a + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254736a9b818f8f6c3819ac393d6b7f7854db18caf10ce923e83f8e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b84cd00d3fb44ad35659ffa23a7536b54efc59aa2044b07586ad +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b009c459289fb3451ce340c21aefbeab59707c472c0b532e3758a1fdb21962b27523093bcb2a3dfce853b494d6ea805a5fc329d60b8aee3304bec99837f50477fe78a4b351f61883d824 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=76ec40c6107efb6f7a22addff790390d82eef906568d70ee8ad03d8bc70fe5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4d4e7a4916c6202c5c7d4cfc502fc7d26f5ad42c9a93023a07dc09e47297e7 + +handshake=Noise_XN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fdd2b7bd566405af7fc55d1ea22eb9a0 +msg_2_payload= +msg_2_ciphertext=037099440bbf00ed48e8e128d88e1ef2306f1b6e68f27fa225aa4b712d77baf42d2aeaa369a2453ca4fac292728eb176f185485e89192e67e6533e3be6e62fd6 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c818555ad9a26b3635d18f4056dc23fbb91c3d3a7a0ec77b01ad01542bccc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e55862d8ebce08d0f83f774fc665146e3de69dd2642884d8613c7a93fd698 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254438d0cdbd30fa2a6212df592afa39463 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f70c2b60d3681c4ae1464b219d601939 +msg_2_payload= +msg_2_ciphertext=8d8c26c8c2048e031c6315e24093d4ad18b7efff7595b086239c24068e3db491bd66a891f64d386afd67ae979156a33405ea115b17b0bcbbbb410662d5000700 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=899e34bc0ead03fba60e56cfd11cbb3790834e6d5c23a10dfa0b93acccc900 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6e85b7d7a6c44fb89e92477ec4caf02ef9abaede5a43eb303676eb7dc4f6e9 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548a5d22bc1f57918704666014d605651c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846640f652850ce7973035f8662ede800b3d +msg_2_payload= +msg_2_ciphertext=77d0e47e4dbb723e616b6f24738e459ea8e98a574f6e59732204f0363e69879fefe52aedafb1eb16cd73b9bf018195ac6115f19155faf159940e8934c48fc3d2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c651eedb26764976c359cd8f3b7e6c6cf61dec2a8e9e7cdabed1e0e5ae7cde +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=caf2c606303c4d12eddf43c5bb8330e86230cb2d8bab3dcf4eadd40776acc1 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625415541c87fdd7cc758cddf3d74585ddfd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662f44198fd9ebd0ef63b19c0a319d954e +msg_2_payload= +msg_2_ciphertext=2c5a5be592acde69362c483d714504e4fb32031199e3b8e7c9052ce199b3b04520cbdc05aa35762b015bcbe72ee32c53f88973ca7a77023b599f7c12fc177a49 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd75543aed4fbaaa884e485c7f3f7847c2dd2c5dd6c669d81399bad151b357 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=aaf79ee8c46da36c2998983b081475ce0c55c22a2c03b6f5c36c6714ac589a + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543cd5f617b6935cd7c18512eb96cab112 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b64a7ac6d3a4f90d88f77ecee3edfc23 +msg_2_payload= +msg_2_ciphertext=b009c459289fb3451ce340c21aefbeab59707c472c0b532e3758a1fdb21962b2f228fcc2420f9dd59b93ab17cd64307b10077ab83231601f42d55bf8b11d5eaf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=76ec40c6107efb6f7a22addff790390d82eef906568d70ee8ad03d8bc70fe5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4d4e7a4916c6202c5c7d4cfc502fc7d26f5ad42c9a93023a07dc09e47297e7 + +handshake=Noise_XN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a14dd9325bc6f396704c83029bb8ee2c682ddefcc95ab27a5705 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=037099440bbf00ed48e8e128d88e1ef2306f1b6e68f27fa225aa4b712d77baf4f298f5dd39297c240ab2ea3bcf06a08d9a894802e80e97ef1c9692f95413dbbb7a274f5b3c8379785a73 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c818555ad9a26b3635d18f4056dc23fbb91c3d3a7a0ec77b01ad01542bccc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=5e55862d8ebce08d0f83f774fc665146e3de69dd2642884d8613c7a93fd698 + +handshake=Noise_XNpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c66d55a16b9cb77895dc547b0a9dacd026081933e9a2f5ba3316 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b78d0157146db12f98a92d0d04ad4f6bcf0eb10295eadb3ce68d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8d8c26c8c2048e031c6315e24093d4ad18b7efff7595b086239c24068e3db491ab26939a8b927dd8b6899c1ef8cd05681ca387a1f28499c8efffe90b8a20b0d0c5492cd30da15886983f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=899e34bc0ead03fba60e56cfd11cbb3790834e6d5c23a10dfa0b93acccc900 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6e85b7d7a6c44fb89e92477ec4caf02ef9abaede5a43eb303676eb7dc4f6e9 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625431ae431ebbf2fffee5c46dc4fe2e28e420faeb5d7d6fdcd9fd1e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b5554432a018960a5ddea9dc4722dafccb155ccec727f7e117db +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=77d0e47e4dbb723e616b6f24738e459ea8e98a574f6e59732204f0363e69879fb33359c30072d3d679a758fafa47b4a88ad399d3f9c470db7708825d5a32cede80e83b39da876ebd32ec +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c651eedb26764976c359cd8f3b7e6c6cf61dec2a8e9e7cdabed1e0e5ae7cde +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=caf2c606303c4d12eddf43c5bb8330e86230cb2d8bab3dcf4eadd40776acc1 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d0fbe4d8c565b9a59d36c37761f6baf2fadacb82f65cdcb0e7a0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665489a70f5e1b78b65e0ed210acf243c4cd719fe17329c873d089 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2c5a5be592acde69362c483d714504e4fb32031199e3b8e7c9052ce199b3b0457cc90677431269e0be999225605d0e473f9258c2910cd02a610afb1a9d02f62b1a42252cc3490723e384 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dd75543aed4fbaaa884e485c7f3f7847c2dd2c5dd6c669d81399bad151b357 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=aaf79ee8c46da36c2998983b081475ce0c55c22a2c03b6f5c36c6714ac589a + +handshake=Noise_XNpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254736a9b818f8f6c3819ac0ececbf4e29bd4ffb897c3d0f6ba0fb5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b84cd00d3fb44ad35659d39abc84ea30dc658b3e678aa780bd53 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b009c459289fb3451ce340c21aefbeab59707c472c0b532e3758a1fdb21962b297cbe2138dce7b9a8078056e25c2ea8f5fc329d60b8aee3304be7e07903593cb5c9efad256bf8e06381c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=76ec40c6107efb6f7a22addff790390d82eef906568d70ee8ad03d8bc70fe5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4d4e7a4916c6202c5c7d4cfc502fc7d26f5ad42c9a93023a07dc09e47297e7 + +handshake=Noise_IN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666e3f19dc99a2257db910145fa6e54aef +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9ccb684459ec247c656f7a9c582a018aac429546bdee1199a1ed61ba49fc64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39614a2f4324d2407d903c372a779b30fd32fae1c5b6d69cdc0877cae101ff + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471caa66028f64280a10cdb259a0f0ee1c59b656bb9366bd2a76f8e42a9bebed7872be750256a0ce3dd0b8d85daee1094b8ed982f1c2a6657ff978086d16874d4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661c71ad2acb743655448c1b44eb19eb7f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=524b10cf461ef1f535017e250c8fe51471fb22093f7aef578485f282f7af0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6d27cc209baae7deb036ff0c7c45a3c0c7b86d1949ff81570da6e319323c08 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541ce4cd9b7ed42c5afaac1903aa6b83bf2665bf49b278784bed2a8d8ca87f34402fdb485d8cfde58838035a57e1ba4e8da2957ac4c7de5d2725b56092d25a7177 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660e1884abae5c79aec17fe6ba6b321f1c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9afced7a00a7d235716c18a3cd21737541e0ce919babee1b4106da009fd889 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=65783176595aba309742bfdf98f1c699ee18b65e091571ff41ef7f3e658b4d + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549138f71daf8a8ccad5990ffd2d892da9fbcf2b41c95e11f1d48ed3ade358c32f7ea8eeaabc9629b368b2e98e0f3733be7225d72099f7df6538e48a8c60dce748 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f10361bb35702893ddbf2c2c632d849c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be487fd9db2f9d9dd8ecb6a2c071a8ebcf71e344d535ecb0376efc8890726d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e43bb8a33bdf3307795da4a4d99d691922794058217d4c4902cef80d1b94ed + +handshake=Noise_IN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466883df2067301b17472bc17c3aea78ff04f20412f5f100390fd79 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9ccb684459ec247c656f7a9c582a018aac429546bdee1199a1ed61ba49fc64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39614a2f4324d2407d903c372a779b30fd32fae1c5b6d69cdc0877cae101ff + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471caa66028f64280a10cdb259a0f0ee1c59b656bb9366bd2a76f8e42a9bebed7872be750256a0ce3dd0b8d85daee109442a2e41e0634afc367f0ce923a70cf9bd6c4db73bb0a0803f10d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663536123ea26b1bfcf393c34e3298477c533893ebfc51cbf9193b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=524b10cf461ef1f535017e250c8fe51471fb22093f7aef578485f282f7af0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6d27cc209baae7deb036ff0c7c45a3c0c7b86d1949ff81570da6e319323c08 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541ce4cd9b7ed42c5afaac1903aa6b83bf2665bf49b278784bed2a8d8ca87f34402fdb485d8cfde58838035a57e1ba4e8d14e124433912c24fe0422740d71e57f17e357266751d7d99aba3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fd0bf78bd69757b645a2d07e6a5fe7582a47bdfba1bbcb3cacc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9afced7a00a7d235716c18a3cd21737541e0ce919babee1b4106da009fd889 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=65783176595aba309742bfdf98f1c699ee18b65e091571ff41ef7f3e658b4d + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549138f71daf8a8ccad5990ffd2d892da9fbcf2b41c95e11f1d48ed3ade358c32f7ea8eeaabc9629b368b2e98e0f3733bede18b3b48a6276edf76a81785394b60e6d181d0b55147e05997d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667e3677d51882a717bfafeb6e28ceb9957567363ba37c8a809db0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be487fd9db2f9d9dd8ecb6a2c071a8ebcf71e344d535ecb0376efc8890726d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e43bb8a33bdf3307795da4a4d99d691922794058217d4c4902cef80d1b94ed + +handshake=Noise_IN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663030d12e83fc1c593b562909667508fb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9ccb684459ec247c656f7a9c582a018aac429546bdee1199a1ed61ba49fc64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39614a2f4324d2407d903c372a779b30fd32fae1c5b6d69cdc0877cae101ff + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471caa66028f64280a10cdb259a0f0ee1c59b656bb9366bd2a76f8e42a9bebed7305e7a3c409dd4ba92d3fc3f3f8d763c46d6344acf2941446c9812a1286cb04d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666d7c1191cd68a34ba4b64c5e58c972a0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=524b10cf461ef1f535017e250c8fe51471fb22093f7aef578485f282f7af0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6d27cc209baae7deb036ff0c7c45a3c0c7b86d1949ff81570da6e319323c08 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541ce4cd9b7ed42c5afaac1903aa6b83bf2665bf49b278784bed2a8d8ca87f3440ed8d78ab07ed6b569d0fc538be2a8220c6b583f1bffa1acc148370953f45cd11 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846621ddef7c2f3b01b8748714bdab2937fd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9afced7a00a7d235716c18a3cd21737541e0ce919babee1b4106da009fd889 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=65783176595aba309742bfdf98f1c699ee18b65e091571ff41ef7f3e658b4d + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549138f71daf8a8ccad5990ffd2d892da9fbcf2b41c95e11f1d48ed3ade358c32fcd3bed0595f69641adbfdd57ab1dc085a124a2b362fb05d05f1e655d15fa290f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664a4abe3680fc325b700f59d5c46985d1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be487fd9db2f9d9dd8ecb6a2c071a8ebcf71e344d535ecb0376efc8890726d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e43bb8a33bdf3307795da4a4d99d691922794058217d4c4902cef80d1b94ed + +handshake=Noise_IN_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466883df2067301b17472bc62ad68cabba7bc80654d521b7a892865 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9ccb684459ec247c656f7a9c582a018aac429546bdee1199a1ed61ba49fc64 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=39614a2f4324d2407d903c372a779b30fd32fae1c5b6d69cdc0877cae101ff + +handshake=Noise_INpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471caa66028f64280a10cdb259a0f0ee1c59b656bb9366bd2a76f8e42a9bebed7305e7a3c409dd4ba92d3fc3f3f8d763c42a2e41e0634afc367f0dde3a61bd4a359193386bca6e46e72b1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663536123ea26b1bfcf393b8cca304c5aa1b4646aad82de257ebcf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=524b10cf461ef1f535017e250c8fe51471fb22093f7aef578485f282f7af0e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6d27cc209baae7deb036ff0c7c45a3c0c7b86d1949ff81570da6e319323c08 + +handshake=Noise_INpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541ce4cd9b7ed42c5afaac1903aa6b83bf2665bf49b278784bed2a8d8ca87f3440ed8d78ab07ed6b569d0fc538be2a822014e124433912c24fe042705ce2c0d3705e137ee0734f70240170 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fd0bf78bd69757b645ad82bb4ce6c5bab13a549bfe52cdc2135 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9afced7a00a7d235716c18a3cd21737541e0ce919babee1b4106da009fd889 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=65783176595aba309742bfdf98f1c699ee18b65e091571ff41ef7f3e658b4d + +handshake=Noise_INpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549138f71daf8a8ccad5990ffd2d892da9fbcf2b41c95e11f1d48ed3ade358c32fcd3bed0595f69641adbfdd57ab1dc085de18b3b48a6276edf76ae73f5ad4478d00547bf6d0cf9f6a4121 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667e3677d51882a717bfaf6fa3e9f062a27f45029aa7e50a76aa13 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=be487fd9db2f9d9dd8ecb6a2c071a8ebcf71e344d535ecb0376efc8890726d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e43bb8a33bdf3307795da4a4d99d691922794058217d4c4902cef80d1b94ed + +handshake=Noise_XK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254808088fc0cc85acaa69a883a6b10211a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466286fbb8efb3a91d14bf3df8a8558e549 +msg_2_payload= +msg_2_ciphertext=eb0b6ca5591599c72f921ad0ee2f37097eb0ff39f6d0b68a2db79458821fa52e94b656504f3b4b0b18ac3fb1621728400aff3211b974726a9a12b35dfc30d1fb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ee724c997ff942b0191c1e6f5dd0b63dd2dcdddbe740adc75cbe972e6e817f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1062ec47c7b6feeedcf8a18eca1349f029c9e101ce51063070050e22b42459 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549a21cfbb9f17fa94ba7f0772b63bfd04 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667497196f76f843d812307b6e089bd401 +msg_2_payload= +msg_2_ciphertext=917f0f36d76ff8028268bd926d6386e350b2f199ca77092c2426a264fb27e6de6720440ea0d07d2f6db823d03b00178e002b4eb9e68e18c6bf602ba2f95631ce +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ece23a617f504b3555121ff562b205ddc2f7f7bce45500f4c4754f3c13b37f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=523dc14e40b73b52c0383053ae49138119ed42714c9bb554f01090708218f5 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545fc5fd96bdd2ee25cbd02439e074689c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666e8ddad12bc56173163ea9ff4442e7d6 +msg_2_payload= +msg_2_ciphertext=da322a93e2ace2fb5424e6105985a4fb09cc20e95dea52a6871c20a5f0630e00b00d58799260c01562b7c62a16c5540facfad1e8a3876299cc921579b2525925 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3d0d4a2d2dc5e9718cf69433752c64f55741eb64656f0cadc04fd0c0e3dfb1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25107eb349768fddc230bcb47918d0dbef1e9dd0441a8b5fd47ee3db5be24 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546ebbf33e299ae9c4d3ecdadc5d8e81f1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466abbff32c51bb4b66b1ef2a158c4c9be1 +msg_2_payload= +msg_2_ciphertext=b0a26ddc196850030b2daea0618577de52cd4b1f96707c49a36c7eaf9bf1bc34f87fea270ff9864d9bd971fa4f5a703d5d0eb7bdb0335875617837d3b4c07c6a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6213b458869a66251d0fc561e406fe4053d82027e1178b7927f06911ec3a5c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3c70914788bc2c254e99114ae697f665d34346627857042c0594027ea4d0a6 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f1b593f13b4cd41cea65b28e468b0b3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466712b4787510ebbf87c665cb9e83ff555 +msg_2_payload= +msg_2_ciphertext=cb3ddcf291a8c6b1af42ad1562902f60b3e7e51aa0f6343391e32e745e1169e751ab42db60d7551e53009c4af681fce89c0305248e2b5de621e3d3540e18c992 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=88c083dea66b4e394e6eb1a2be53b312843d8ca646a33ccfbb3ed35b3daa53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6732c169f023972e0e83c494bdb771ab5ba60fe609610da42d8fd752cee3aa + +handshake=Noise_XK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254513029d2b4b8b9fe5f9f31b454bddd12afca1145e94ba04df016 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466952886df4d27c408e437cfe25cdf30274e59b83f527df211d907 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=eb0b6ca5591599c72f921ad0ee2f37097eb0ff39f6d0b68a2db79458821fa52e6ea3fc0ebc929c08541fa3d84ba852dec9476064b9a9203e8e3fe3834bc45201e24e6b1c19f0039bd0a3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ee724c997ff942b0191c1e6f5dd0b63dd2dcdddbe740adc75cbe972e6e817f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1062ec47c7b6feeedcf8a18eca1349f029c9e101ce51063070050e22b42459 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547b59e69f28ee958ea6ec286d88a478df18c37c290409b2f305fc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846655be0dd1239ef6aacc00e2ce0033ef9570ae5b1cffdb3d9d3665 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=917f0f36d76ff8028268bd926d6386e350b2f199ca77092c2426a264fb27e6def31d422a36ba3e3b6347f914a24ebf9e92483ea0ae34710f38b31b7585040107da201115c7f61909ec55 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ece23a617f504b3555121ff562b205ddc2f7f7bce45500f4c4754f3c13b37f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=523dc14e40b73b52c0383053ae49138119ed42714c9bb554f01090708218f5 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625488a0b01ef66d73b2fb0a07321d83f1680059c05be6fc73edc288 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846628eb3b4c42ce0e4b53d9eb540dbff9cff29fad9648742f88b0e1 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=da322a93e2ace2fb5424e6105985a4fb09cc20e95dea52a6871c20a5f0630e000afa05043632f4e6947eb243c2f4cabe10ec74c7fc4899c810657c6bb56e2fecbe312e445a29caf8f322 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3d0d4a2d2dc5e9718cf69433752c64f55741eb64656f0cadc04fd0c0e3dfb1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25107eb349768fddc230bcb47918d0dbef1e9dd0441a8b5fd47ee3db5be24 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3c1632d409d0c434982a274e3c5fb542081635f8a21000e4c9d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf994581db893a145c65da8ae390d2ec36b8710553712ff8eec1 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b0a26ddc196850030b2daea0618577de52cd4b1f96707c49a36c7eaf9bf1bc34b54b17adec69bae75235275b00362611dc862adcd710a1c7224b3f630b4b4c849e193738a6bdc24c4b5e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6213b458869a66251d0fc561e406fe4053d82027e1178b7927f06911ec3a5c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3c70914788bc2c254e99114ae697f665d34346627857042c0594027ea4d0a6 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254800450454355b9d11d4bdb67aaee48e1576aab47af4286a78e66 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0a4fd69aab20cdafe7c937b951e8590276356a5453e89e5da1d +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=cb3ddcf291a8c6b1af42ad1562902f60b3e7e51aa0f6343391e32e745e1169e78d6ae76bedbaa0e2ec33f27dd63397beba6045f20fae93dfb40afbbf27dc991c624bacb8d90acdf47b60 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=88c083dea66b4e394e6eb1a2be53b312843d8ca646a33ccfbb3ed35b3daa53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6732c169f023972e0e83c494bdb771ab5ba60fe609610da42d8fd752cee3aa + +handshake=Noise_XK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625412016aff62eaff30a75a5c0c2d0042a0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fa6d908607c010a4e27f592aa3e77db0 +msg_2_payload= +msg_2_ciphertext=eb0b6ca5591599c72f921ad0ee2f37097eb0ff39f6d0b68a2db79458821fa52e15a80d50e518ff27cdad772e19a43917bb69687b02856c53a828c04ed8ff57b4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ee724c997ff942b0191c1e6f5dd0b63dd2dcdddbe740adc75cbe972e6e817f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1062ec47c7b6feeedcf8a18eca1349f029c9e101ce51063070050e22b42459 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545024b4b7b169e3f9e56a785643af64db +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f8734d1674650e362c81c6c774638696 +msg_2_payload= +msg_2_ciphertext=917f0f36d76ff8028268bd926d6386e350b2f199ca77092c2426a264fb27e6de6d0830f27670e86e0517c7b7e3fefb0681306e548e88b9a1879970348fca1541 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ece23a617f504b3555121ff562b205ddc2f7f7bce45500f4c4754f3c13b37f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=523dc14e40b73b52c0383053ae49138119ed42714c9bb554f01090708218f5 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547667b794a46490293262417fee000006 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665ba9cdd7eab34372accb31399188da5b +msg_2_payload= +msg_2_ciphertext=da322a93e2ace2fb5424e6105985a4fb09cc20e95dea52a6871c20a5f0630e0042e34692374f7e53b893d8509eb32f7fd8b548fc1e3a5a90eebdb7ccf6bff0a5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3d0d4a2d2dc5e9718cf69433752c64f55741eb64656f0cadc04fd0c0e3dfb1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25107eb349768fddc230bcb47918d0dbef1e9dd0441a8b5fd47ee3db5be24 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544eca8fcfb3e6e255215ded2bcd48afbf +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846603fddfe0f6ae65fa28cc181cd81faeee +msg_2_payload= +msg_2_ciphertext=b0a26ddc196850030b2daea0618577de52cd4b1f96707c49a36c7eaf9bf1bc34b1202b8bffd5ed08e5de027c5b84a7158fe52e8f576bb6882f758bacd60f3c83 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6213b458869a66251d0fc561e406fe4053d82027e1178b7927f06911ec3a5c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3c70914788bc2c254e99114ae697f665d34346627857042c0594027ea4d0a6 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625440285ac3362d63eb8ced07422fb6cf25 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846681421bc40d383c443bc45dd96b4ef485 +msg_2_payload= +msg_2_ciphertext=cb3ddcf291a8c6b1af42ad1562902f60b3e7e51aa0f6343391e32e745e1169e7ebdfbe67365243ee68f0efb0d5717e1b69daddf1284769341892aa3a4710b976 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=88c083dea66b4e394e6eb1a2be53b312843d8ca646a33ccfbb3ed35b3daa53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6732c169f023972e0e83c494bdb771ab5ba60fe609610da42d8fd752cee3aa + +handshake=Noise_XK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254513029d2b4b8b9fe5f9ff602b54bab72e3edd208f6f0abed927b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466952886df4d27c408e437397eab406b5d57694f8cae1bfa84a7dd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=eb0b6ca5591599c72f921ad0ee2f37097eb0ff39f6d0b68a2db79458821fa52e06b2be633d0635b9d56d487202e4204ac9476064b9a9203e8e3f70353e310a53186c458753fda9a9ea81 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ee724c997ff942b0191c1e6f5dd0b63dd2dcdddbe740adc75cbe972e6e817f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=1062ec47c7b6feeedcf8a18eca1349f029c9e101ce51063070050e22b42459 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547b59e69f28ee958ea6ece01b095ca48313f07a8deb1640007c88 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846655be0dd1239ef6aacc00d4f1a20d1b426381eadad2ad8428dfe4 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=917f0f36d76ff8028268bd926d6386e350b2f199ca77092c2426a264fb27e6de0d2bfdd01ecd6c54321b7e27497573ed92483ea0ae34710f38b335d4132f6bafcccfaf6c60009cba4ea3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ece23a617f504b3555121ff562b205ddc2f7f7bce45500f4c4754f3c13b37f +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=523dc14e40b73b52c0383053ae49138119ed42714c9bb554f01090708218f5 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625488a0b01ef66d73b2fb0a89359dbca1e95a546531ed9387f06e59 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846628eb3b4c42ce0e4b53d9622ca4eca51b9978eb0ae4617fe43b7b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=da322a93e2ace2fb5424e6105985a4fb09cc20e95dea52a6871c20a5f0630e00dd49f57036508780d776a79187d98f9d10ec74c7fc4899c8106536d6a7ec0636185ac76582c8fbef94a3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3d0d4a2d2dc5e9718cf69433752c64f55741eb64656f0cadc04fd0c0e3dfb1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f25107eb349768fddc230bcb47918d0dbef1e9dd0441a8b5fd47ee3db5be24 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3c1632d409d0c43498218e8e9e0d575ff260499ad54f0342435 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf994581db893a145c65a7c7d45d5a2b7d10e3ebaa4c84fef736 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b0a26ddc196850030b2daea0618577de52cd4b1f96707c49a36c7eaf9bf1bc3443eef8be3e6057a7169b08e1a0054fe2dc862adcd710a1c7224b58933c565f2d339fe7bb2b5d1e53d1cd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6213b458869a66251d0fc561e406fe4053d82027e1178b7927f06911ec3a5c +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3c70914788bc2c254e99114ae697f665d34346627857042c0594027ea4d0a6 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254800450454355b9d11d4b81a05f9e0cbfc6e5086837041b04d043 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0a4fd69aab20cdafe7cc5e114e8ebd132e1a2afca39d3c1729c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=cb3ddcf291a8c6b1af42ad1562902f60b3e7e51aa0f6343391e32e745e1169e76a3b6eadf256a4f2e5c0eff96d18d97aba6045f20fae93dfb40aa1374c50db5b917c4e6bab8c41f9b9ac +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=88c083dea66b4e394e6eb1a2be53b312843d8ca646a33ccfbb3ed35b3daa53 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6732c169f023972e0e83c494bdb771ab5ba60fe609610da42d8fd752cee3aa + +handshake=Noise_IK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549e5f11977b6b44e9245c67330f3e51de6fc540b9b740f21673e7eb5dccadbfb1208a0530f27f8b630c81e3cf775e9d2b632ab3ac64125105a17a6a7173315506 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660cc75863504a0d3eef43e5ea39e1a698 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17185d8a376d58b3119840b99b784085186a622ba32b1ede9c99f2751509e9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db1d6ba1f8fad6b62e7d3f421a413389d609e5ec601b65e5bfa110c7f0c733 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ba236852ef2b3162575105b0b33d4c6dd100842740d0c9be12622a57ee373e2cf63cca3e01b4a6ed0db101472ee9d420b0bbb911a0cc3bd5e7972ea44fecee8b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665322064e503c875ffec58103e63c3a86 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c01ee1d733b16ed26b81d16bcbdfefe0583f6bb7b917d205ea6590b6e34b1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbb884cb5c480ba6f73efa28c9c17633385e48355918a67989a5171e51e85b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625458f289ffe3283f14bdf492ec8bdb979b13c98eb5d07a8f7eb9d121303d8d200f0a159e84f04aec162883d80f6ee185e80cdc9aa5d86d9bcc163cc0033b8d33e2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668c918bfc3507fd1385ab27e3a4dba0a0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=64fd4d007240834917ec1660292c5605562acd3ce322544f477dd84c47aadc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49969eca3ef61dd7c049da3a2b2f4170475d452e81ee61cf637e5c2e17905d + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce891740b98a5f5c16f135436cb725e1fe702acd4c5a1d5cb4d2c528d4574b93b59172cabb2f8a6274486923c7d6693be2d801740a3b06edd5a0278816d3bfbd +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cc8e335580292058f46ced567b9ff86a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c53f53e2030e27fb57f8cda4c39ed1da26bf58966b52d7dc404876539062bd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f28b6a586437b0c6f7a3571b9267a65f6e3bab0fee53e71037355fa3a4008 + +handshake=Noise_IK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549e5f11977b6b44e9245c67330f3e51de6fc540b9b740f21673e7eb5dccadbfb1208a0530f27f8b630c81e3cf775e9d2bb312954cec80357f078868c439a5fd9b464f38adf2f6e56a0f5a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b65172025a9545030cfab48a24e4de47e0f9574129c6458722cb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17185d8a376d58b3119840b99b784085186a622ba32b1ede9c99f2751509e9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db1d6ba1f8fad6b62e7d3f421a413389d609e5ec601b65e5bfa110c7f0c733 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ba236852ef2b3162575105b0b33d4c6dd100842740d0c9be12622a57ee373e2cf63cca3e01b4a6ed0db101472ee9d420f3f538a30d6559cac7dd4a4f14a567547f6d6a98e2233bc08a3b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846690b49233385ad8dfcc23a7eaf53e993748e215d961aaa6aee8e6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c01ee1d733b16ed26b81d16bcbdfefe0583f6bb7b917d205ea6590b6e34b1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbb884cb5c480ba6f73efa28c9c17633385e48355918a67989a5171e51e85b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625458f289ffe3283f14bdf492ec8bdb979b13c98eb5d07a8f7eb9d121303d8d200f0a159e84f04aec162883d80f6ee185e8cb7e0fa59d5f1b87833688fba8e81572e05bcc5347dc4754e004 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e7aec10cef4cebc40f678fd4b38db7f49b542d3ed6061e099ea +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=64fd4d007240834917ec1660292c5605562acd3ce322544f477dd84c47aadc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49969eca3ef61dd7c049da3a2b2f4170475d452e81ee61cf637e5c2e17905d + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce891740b98a5f5c16f135436cb725e1fe702acd4c5a1d5cb4d2c528d4574b93b59172cabb2f8a6274486923c7d6693bee9fd1e8b3e88194ca3b46f2b2ed2549b5ca881c5ae0fcfa0b30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664065db2bb1884c3e44120d9374fa0fa4cc695182408697948940 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c53f53e2030e27fb57f8cda4c39ed1da26bf58966b52d7dc404876539062bd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f28b6a586437b0c6f7a3571b9267a65f6e3bab0fee53e71037355fa3a4008 + +handshake=Noise_IK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549e5f11977b6b44e9245c67330f3e51de6fc540b9b740f21673e7eb5dccadbfb18620823a2dc5df3eef9552dbfa3eaef69c1c7e045b0905bce8961fb9dc3b9154 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846671319c9183c5b8207cbfd8af0063cdc7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17185d8a376d58b3119840b99b784085186a622ba32b1ede9c99f2751509e9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db1d6ba1f8fad6b62e7d3f421a413389d609e5ec601b65e5bfa110c7f0c733 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ba236852ef2b3162575105b0b33d4c6dd100842740d0c9be12622a57ee373e2c9090737e80f23255017e7412f0e35b41d3bb273dcb080bb680e05542b200ddf0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668ea7124d61b15a2af4db1649c7f5c67f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c01ee1d733b16ed26b81d16bcbdfefe0583f6bb7b917d205ea6590b6e34b1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbb884cb5c480ba6f73efa28c9c17633385e48355918a67989a5171e51e85b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625458f289ffe3283f14bdf492ec8bdb979b13c98eb5d07a8f7eb9d121303d8d200f16acadcde5e3e159322f07d637fb82466ffffcee8c135ff2d3468091ad1ac965 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660a9c9ba7901c8cc2095933f61539ebaf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=64fd4d007240834917ec1660292c5605562acd3ce322544f477dd84c47aadc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49969eca3ef61dd7c049da3a2b2f4170475d452e81ee61cf637e5c2e17905d + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce891740b98a5f5c16f135436cb725e1fe702acd4c5a1d5cb4d2c528d4574b9335f9e93f8bc1c9fe0bf9e671e91604472252ac533a0b7673a69e050fc6c555f9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846625ce0bc015e15cc05f95114e8615e107 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c53f53e2030e27fb57f8cda4c39ed1da26bf58966b52d7dc404876539062bd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f28b6a586437b0c6f7a3571b9267a65f6e3bab0fee53e71037355fa3a4008 + +handshake=Noise_IK_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549e5f11977b6b44e9245c67330f3e51de6fc540b9b740f21673e7eb5dccadbfb18620823a2dc5df3eef9552dbfa3eaef6b312954cec80357f07882a687c02e62bd6e56c8fe017f2463049 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b65172025a9545030cfaaa2d22caa6cc27ccf97a1e6b683f6b7c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=17185d8a376d58b3119840b99b784085186a622ba32b1ede9c99f2751509e9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=db1d6ba1f8fad6b62e7d3f421a413389d609e5ec601b65e5bfa110c7f0c733 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ba236852ef2b3162575105b0b33d4c6dd100842740d0c9be12622a57ee373e2c9090737e80f23255017e7412f0e35b41f3f538a30d6559cac7dd68f4009e9b60995b9c26ef2ad7b301d1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846690b49233385ad8dfcc23ec9268f5fbc7595e89a031ce59fa882f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c01ee1d733b16ed26b81d16bcbdfefe0583f6bb7b917d205ea6590b6e34b1c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cbb884cb5c480ba6f73efa28c9c17633385e48355918a67989a5171e51e85b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625458f289ffe3283f14bdf492ec8bdb979b13c98eb5d07a8f7eb9d121303d8d200f16acadcde5e3e159322f07d637fb8246cb7e0fa59d5f1b8783366849fcc7d25b2490e6ea2b7cce88d13e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662e7aec10cef4cebc40f61a8390b590d6bb5e55e5aa8f45bda184 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=64fd4d007240834917ec1660292c5605562acd3ce322544f477dd84c47aadc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=49969eca3ef61dd7c049da3a2b2f4170475d452e81ee61cf637e5c2e17905d + +handshake=Noise_IKpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce891740b98a5f5c16f135436cb725e1fe702acd4c5a1d5cb4d2c528d4574b9335f9e93f8bc1c9fe0bf9e671e9160447ee9fd1e8b3e88194ca3b7dd0c0f15d5ba12f1280b747e9755206 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664065db2bb1884c3e44120e547598980a2e5918807a5273b89cd7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c53f53e2030e27fb57f8cda4c39ed1da26bf58966b52d7dc404876539062bd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f28b6a586437b0c6f7a3571b9267a65f6e3bab0fee53e71037355fa3a4008 + +handshake=Noise_XX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692e5b8dda95b4ec55e42c2cbded11735474b3612a895298bcb02e8469353fe827273e4a7aadfc1aa32578b46bce2006fe1482f062e2f27e43ad23e67a304c030 +msg_2_payload= +msg_2_ciphertext=ac3087e2342498dfa6606faf700dc5782b9612bdbc8bbb67a87181baac2d693d2f8df70600534bcbd389bbbf733550ae3e7e9a78f80aafa70d6211640223800d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2dcb8503b438910b2a2ffcf242ef705e6cce2d25bd30444402427981ee2064 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=56d2ce5c1e7e28b7406b99aff512114313b811e17c0af6497baa906165ba31 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f2f462471c5d60ba0088de4eff15e53c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466be325d2fad8902f6af1f3b2b5acc9eab588b638e7e6c2e488d433d28690843f2d911861dc176203f80dba4198ac1786a916a77181cb8c24178d9ec84f88f5d4e +msg_2_payload= +msg_2_ciphertext=1e65fa56a639797ffe77d0d2951c4e2b3ec3ff11878bc08d9d1907247b9b01ab58a8c21ea7a521466a81d82e0fc7b5a624bcbc25fd46682f7588ed21c5edb914 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d38f1c0a508dd95e6a8a567c8931a8637bad28b91d9564bd9c8fa23deaa220 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=895cf67ef6bc4e9116cff01e1891ecfc3413847ff1aa6c81ff9caf5d917a7b + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d54b25e517e5d9d9d1443c747c2b31d5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666dfab3251da0797a6fde63e3bfeca2f0f74fa7162dd3825426965c0f2a0fc90a5657879f6810cfc3709e05e9153b2ae7fdfe94a9d8b2da4c04e0500e8ea8b94a +msg_2_payload= +msg_2_ciphertext=4a7ae3d865ae62214d81c67bc6134402ddb479fabf4bbd95f70dcd744d48e91d8a9ab3aeff5a6a45eeb8476ece42c0e3c1023fb1af8e1670fba5eb5dbc1fb648 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d3ec65abb14824f326728eef1a0d957839c2a31fcf8f6a8444c3ad12e92565 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4bc899aa61919f501f103187883abc24ba96d80bb9152d4b04fd09763384f8 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625440589b2466ae4b8ae6b6656661608de6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ea4d8909862193d7f28ce230e8f8fdd52e2c7c32b59cc81b8c8b869025e7645ba40ad8ca10cfa1e971c4da023e7343d02a8c1c65b1d68eefae2f4714fc10f7b +msg_2_payload= +msg_2_ciphertext=e37f84e33bdb15ba63178cff0ea5946e4aa4f71e86ea0b3dd8e885baa63ead5591d0e50d96ad81a539e2ee63a5dec7710cc7e4dab085c993c022b961e3b500ce +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=337c476f38adead5eec91eb6e27edbedd33f5cf702e885c67b25e06fed6475 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f7f94c1464b63d63b099af6faec4a3bbbf861b5bd04314135a5bb666d2e57a + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a399eeb57fa150bf0903a5144931cfed +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466af613726ed79ba171d0ba959f0bafc5949f8e4279fa836af1dac74632da07426cfde6cd9c24984229cef63503e25d9720f21fcd6aeca15edc259b59d5dbde2be +msg_2_payload= +msg_2_ciphertext=435c3d4404fb904058992c956972c09b477b3d5465f8dfaf487205d7c8024e7a7fc6bb767df7acc8c6b2150a1a07c368f2dc33bea0ceb8c05fd775f32d85a0a5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ea30f606b3b7b47433ec08e91298daef7df94faae71de0c396f7a3b194ed78 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f2d28fa9662bd3bc6486d0e2fc2376eca51a747e66357baedf1e36d3b9b804 + +handshake=Noise_XX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692e5b8dda95b4ec55e42c2cbded11735474b3612a895298bcb02e8469353fe8268dd0a1354f3b23c3da9b4f11e91e2f8d221c75462cbc2798cc0fa8e4cfe53cd1edc4717ec17d20245fd +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=ac3087e2342498dfa6606faf700dc5782b9612bdbc8bbb67a87181baac2d693d629aba6b7f84dd26889cc9605e02f2cb5a36853cf1f1ced5ddda5564922cc4ba1e5d7286a0b9794ef6f5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2dcb8503b438910b2a2ffcf242ef705e6cce2d25bd30444402427981ee2064 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=56d2ce5c1e7e28b7406b99aff512114313b811e17c0af6497baa906165ba31 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254866d809eebe6c3d84a3f1d85990e9a886d6b0aca260582337b30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466be325d2fad8902f6af1f3b2b5acc9eab588b638e7e6c2e488d433d28690843f28a0cc0e544065513f76cdf148c3e1b87938775bd82c3a86e2267643e455d0cd71cc1053717bcab764e28 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=1e65fa56a639797ffe77d0d2951c4e2b3ec3ff11878bc08d9d1907247b9b01ab5c812d0fa094b7e823d8ad0c260f119d1350ee3e4725f68b581b3f2a51751ac34b9b9a8b8f6a7f811aab +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d38f1c0a508dd95e6a8a567c8931a8637bad28b91d9564bd9c8fa23deaa220 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=895cf67ef6bc4e9116cff01e1891ecfc3413847ff1aa6c81ff9caf5d917a7b + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254542b41136533a8304a77a255707e1a2d8a823ed6c045fee9e548 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666dfab3251da0797a6fde63e3bfeca2f0f74fa7162dd3825426965c0f2a0fc90ab99e5b81af6b8c0a448f4d1c2d79369223cac5251a120ab78a722e8f74107f28c718b5af7e4523d15d01 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4a7ae3d865ae62214d81c67bc6134402ddb479fabf4bbd95f70dcd744d48e91df4b7bbf5ef4c57a0b340788a746ab69d32f2011af09a5b12c1466af4789c7b7b084f8a56786af64de04d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d3ec65abb14824f326728eef1a0d957839c2a31fcf8f6a8444c3ad12e92565 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4bc899aa61919f501f103187883abc24ba96d80bb9152d4b04fd09763384f8 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da6c52ee1b045a9cfeb401e860c6f8dad9c4750c4a15b09958ef +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ea4d8909862193d7f28ce230e8f8fdd52e2c7c32b59cc81b8c8b869025e76457e2e64fcc610a96b70b4ef648b07d4437992e6627c6b6b97687f6315ae3f979f0b6ad6c4e8ce8ece2787 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e37f84e33bdb15ba63178cff0ea5946e4aa4f71e86ea0b3dd8e885baa63ead559885db6405390f86a481ce9e6793d889cf8779569d616597b16fb3efef2f3436535accde8af36f5cf983 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=337c476f38adead5eec91eb6e27edbedd33f5cf702e885c67b25e06fed6475 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f7f94c1464b63d63b099af6faec4a3bbbf861b5bd04314135a5bb666d2e57a + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cd5279aefbfc171ce82b4ca5c1044ed8a6734a0de58708aa79b6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466af613726ed79ba171d0ba959f0bafc5949f8e4279fa836af1dac74632da07426611a76229186c4cb7020d89b58290d9d5b5bc0b66a4c643d9ecf43a5bfe4bf1052483c506b154561e9c2 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=435c3d4404fb904058992c956972c09b477b3d5465f8dfaf487205d7c8024e7a8e896e684314ab8e896610a945dedb8366ac8fc47095844e8da0305964ea0cc5b74114a419fa1facd127 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ea30f606b3b7b47433ec08e91298daef7df94faae71de0c396f7a3b194ed78 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f2d28fa9662bd3bc6486d0e2fc2376eca51a747e66357baedf1e36d3b9b804 + +handshake=Noise_XX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692e5b8dda95b4ec55e42c2cbded11735474b3612a895298bcb02e8469353fe823d2f9b86e9a08534663b376f8eba4ce7bb56a4e82647d6c17a846c7ea69f9c70 +msg_2_payload= +msg_2_ciphertext=ac3087e2342498dfa6606faf700dc5782b9612bdbc8bbb67a87181baac2d693d73dccbe0d8c4858d1508ebdcb753a5e60f5622374a46e41efb00eba64f71113f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2dcb8503b438910b2a2ffcf242ef705e6cce2d25bd30444402427981ee2064 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=56d2ce5c1e7e28b7406b99aff512114313b811e17c0af6497baa906165ba31 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254afe230e0e90c70cbc586925eab0f8afa +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466be325d2fad8902f6af1f3b2b5acc9eab588b638e7e6c2e488d433d28690843f2318f800a32467ae4ab2051e240291a1bd6993f00169a8ea675e5bb5cba5a139d +msg_2_payload= +msg_2_ciphertext=1e65fa56a639797ffe77d0d2951c4e2b3ec3ff11878bc08d9d1907247b9b01ab03f64171d19600f941ad6056814141f00c5b5d6d041e3474254413ee1bfd117f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d38f1c0a508dd95e6a8a567c8931a8637bad28b91d9564bd9c8fa23deaa220 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=895cf67ef6bc4e9116cff01e1891ecfc3413847ff1aa6c81ff9caf5d917a7b + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625435f58b36487f42de4284c58ba543921c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666dfab3251da0797a6fde63e3bfeca2f0f74fa7162dd3825426965c0f2a0fc90aab54d72f4e993321086d6f6159502b24510534eaf9fa26e099f93814480a7c00 +msg_2_payload= +msg_2_ciphertext=4a7ae3d865ae62214d81c67bc6134402ddb479fabf4bbd95f70dcd744d48e91dc2f7c8ba426fc407af6fcbdbefc136f348937198e636b5dfbabbdfbb9e2bcc4a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d3ec65abb14824f326728eef1a0d957839c2a31fcf8f6a8444c3ad12e92565 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4bc899aa61919f501f103187883abc24ba96d80bb9152d4b04fd09763384f8 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625420e4dc62070a9aebab2b6572e2ae4b98 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ea4d8909862193d7f28ce230e8f8fdd52e2c7c32b59cc81b8c8b869025e7645ee5f681862f0dec10f9dc8d8e96c07b155da7f7b101977ae1d19f12b407a34fb +msg_2_payload= +msg_2_ciphertext=e37f84e33bdb15ba63178cff0ea5946e4aa4f71e86ea0b3dd8e885baa63ead55940ca69900d62a3186db3105276b15f56ef7fd1c850ac561e7363a523d92ed6e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=337c476f38adead5eec91eb6e27edbedd33f5cf702e885c67b25e06fed6475 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f7f94c1464b63d63b099af6faec4a3bbbf861b5bd04314135a5bb666d2e57a + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b7a040ac300959fe34bfe71e0d24f6a0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466af613726ed79ba171d0ba959f0bafc5949f8e4279fa836af1dac74632da07426888d44c76f124e6bb39acc5176271a3e6319e1de8c126261dc7185d14cab1c5e +msg_2_payload= +msg_2_ciphertext=435c3d4404fb904058992c956972c09b477b3d5465f8dfaf487205d7c8024e7a91ab16e67d24b1fdef4dff4b9bf6c76fe01aa2da79da940839db82cf0c8dd98b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ea30f606b3b7b47433ec08e91298daef7df94faae71de0c396f7a3b194ed78 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f2d28fa9662bd3bc6486d0e2fc2376eca51a747e66357baedf1e36d3b9b804 + +handshake=Noise_XX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692e5b8dda95b4ec55e42c2cbded11735474b3612a895298bcb02e8469353fe82b4cd9a14f8ead39d89dfbc1caa392541d221c75462cbc2798cc052f73a84342b5476620ae41849b8965c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=ac3087e2342498dfa6606faf700dc5782b9612bdbc8bbb67a87181baac2d693d79ea79b6110288f4e89aae84921c40605a36853cf1f1ced5ddda854ea5ce29deb956bd1c54de796b357f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=2dcb8503b438910b2a2ffcf242ef705e6cce2d25bd30444402427981ee2064 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=56d2ce5c1e7e28b7406b99aff512114313b811e17c0af6497baa906165ba31 + +handshake=Noise_XXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254866d809eebe6c3d84a3ff5b7f9842209a6bb025a5804dc0de2bb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466be325d2fad8902f6af1f3b2b5acc9eab588b638e7e6c2e488d433d28690843f206009fabe86c879f8d9e2738ee4ed4d2938775bd82c3a86e2267c5764cd7abd871e6263afcc404a5e0a1 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=1e65fa56a639797ffe77d0d2951c4e2b3ec3ff11878bc08d9d1907247b9b01ab46af6720d3d054872b900594d8b526601350ee3e4725f68b581b62bcc4a3a13247dcbceb4e8a9650d90c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d38f1c0a508dd95e6a8a567c8931a8637bad28b91d9564bd9c8fa23deaa220 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=895cf67ef6bc4e9116cff01e1891ecfc3413847ff1aa6c81ff9caf5d917a7b + +handshake=Noise_XXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254542b41136533a8304a77b81b6dfdf040484761f3ccafe691e75d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666dfab3251da0797a6fde63e3bfeca2f0f74fa7162dd3825426965c0f2a0fc90a5dec9479f1ad2799fbd27fdb7fdc056523cac5251a120ab78a72461a4e9de89b862c7414fa11fd5bb881 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4a7ae3d865ae62214d81c67bc6134402ddb479fabf4bbd95f70dcd744d48e91d0583c25739292883c9333532c4da5f3032f2011af09a5b12c1468e7b1eab09321a31a1d2ff6796ac80d3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=d3ec65abb14824f326728eef1a0d957839c2a31fcf8f6a8444c3ad12e92565 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4bc899aa61919f501f103187883abc24ba96d80bb9152d4b04fd09763384f8 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da6c52ee1b045a9cfeb44ece894131cd8d2fb1213bbeca79f626 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663ea4d8909862193d7f28ce230e8f8fdd52e2c7c32b59cc81b8c8b869025e764501a2be4cd48b63a3c74802e86d9b8bd37992e6627c6b6b97687f53a407d8b6afdd43d633c2daebaafc14 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e37f84e33bdb15ba63178cff0ea5946e4aa4f71e86ea0b3dd8e885baa63ead5575db230303120a1dde9a88d5cbd4ff98cf8779569d616597b16f4a9f5ef1dd4f26463290e83402284a14 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=337c476f38adead5eec91eb6e27edbedd33f5cf702e885c67b25e06fed6475 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f7f94c1464b63d63b099af6faec4a3bbbf861b5bd04314135a5bb666d2e57a + +handshake=Noise_XXpsk3_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cd5279aefbfc171ce82b89a9045aed50568afa724bb8f9c0a540 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466af613726ed79ba171d0ba959f0bafc5949f8e4279fa836af1dac74632da07426822f55cfb4baec5d5626d45e9dec6fa85b5bc0b66a4c643d9ecfa433cca204d22000ae309809dbcd2507 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=435c3d4404fb904058992c956972c09b477b3d5465f8dfaf487205d7c8024e7ad29ffdd53f3a0921483a26ab29377e2e66ac8fc47095844e8da0f4e9b114d0ba5db5685ab45d76a7e03c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ea30f606b3b7b47433ec08e91298daef7df94faae71de0c396f7a3b194ed78 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=f2d28fa9662bd3bc6486d0e2fc2376eca51a747e66357baedf1e36d3b9b804 + +handshake=Noise_IX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466695d6599121fe2a7334d2c97732a3ffadbcfd7e6bdb2544697bb5f00916ee3fc5705ded2ea5e74dc4cccd271b3b170c018ece669ee8eb50c1183697979a87056 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=26615f8c05cfc06ba45d92c919ac3646b75c5b98ccc6bf7be435f660303233 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=246f084e1984bada028bdd5706659a090073f4e900983ae7f43938081d0e6c + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f23d888fc466096221d018369dbfd469e8982fe06d5f5403cf73cbae43506d4c019dc3f0ddbe6a8e4cedc9663bbc0666e2e8003f39416bd73417eeacb429f0d3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666dbaa36ddf907742a80f1551f8b7d380adbf8039ff57bf43ffe5f1c2315caca03d159b9f20ec197dade265afb859e24ed346fbf36ad4ac6f225c06a83bb5f7b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ba368d3ceaeb7b4ddea9fa0ec3f6af47bce36ec342a0be54a2bd08e7b57a31 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=003d182934bbbfb5ba808d6e335bf7d155504ae7a7d5f5288d2af34bb05e08 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254730f4c1d260b464346081cd7e638a961153cb165f87bd25c9b26c250e5bb880805b009cde612246770287ee104db35f1ec3dbb8330fb8854782bc70cf926c466 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466129a73114e12a289af04ec9af3e8a49cfc343ba36ce522267a3eedb9971791a6e3a11e74aec9f653fe66e3498ec3f0ba924cdd5b28c0b701b834909dfc1b440d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96efc6df0548c32e43ca4c59eeb2559626095079ecb0ba2be9c8fd6628d844 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f9e72631a890074a8b30f623968e914862330f34ec4e2aa36f6f7b987a3d6 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254336c06ececc68c95a721a5e1108b1d2c29397707cbf738e7a8849fd2ff08d62951cd48325d28bb67c3280fca55c91275b3ef8f17b7ca1768f171c2071903c43f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846691aaca91f9159a9bd67aa886e00a54088edc28c8d38e3a34870cc34fb1305b2a13bd55a7a8052b97ab1bc4ccdcabba822d611d461660deabf4584d1747a222d3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=44f1bd491d21b3e3fe06273ce11e6530122d7314ec4fa74994ee55481f5133 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf9875d0094449a70e60dd5577ed61d03ae2e86b775aca74bf2723ea6b969c + +handshake=Noise_IX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466695d6599121fe2a7334d2c97732a3ffadbcfd7e6bdb2544697bb5f00916ee3fce9879d0ed150af9f2be81aa51c039e9e7b5773f45de6318af93f86d0dc96b99df12aaa638be5a625ff49 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=26615f8c05cfc06ba45d92c919ac3646b75c5b98ccc6bf7be435f660303233 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=246f084e1984bada028bdd5706659a090073f4e900983ae7f43938081d0e6c + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f23d888fc466096221d018369dbfd469e8982fe06d5f5403cf73cbae43506d4c019dc3f0ddbe6a8e4cedc9663bbc06667559f6ca4f3be7e578e55edf0c66945d61065236620e451730ff +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666dbaa36ddf907742a80f1551f8b7d380adbf8039ff57bf43ffe5f1c2315caca5703a32de32a3a7099780894de955a6bf797d76ea657debdad89256c8b7f7c131759900ed8fd0c936cfc +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ba368d3ceaeb7b4ddea9fa0ec3f6af47bce36ec342a0be54a2bd08e7b57a31 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=003d182934bbbfb5ba808d6e335bf7d155504ae7a7d5f5288d2af34bb05e08 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254730f4c1d260b464346081cd7e638a961153cb165f87bd25c9b26c250e5bb880805b009cde612246770287ee104db35f1431211b554223603a05e313043e051745116e15077094aecb596 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466129a73114e12a289af04ec9af3e8a49cfc343ba36ce522267a3eedb9971791a6611fbcdf30357d8d3157a9926c75108d9f704ccf6c61778c12e3a158605089315ee6d9e1a254a26bb385 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96efc6df0548c32e43ca4c59eeb2559626095079ecb0ba2be9c8fd6628d844 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f9e72631a890074a8b30f623968e914862330f34ec4e2aa36f6f7b987a3d6 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254336c06ececc68c95a721a5e1108b1d2c29397707cbf738e7a8849fd2ff08d62951cd48325d28bb67c3280fca55c91275c719b81dc74cf8887220c7858051cacaba08461b443c9f1feafb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846691aaca91f9159a9bd67aa886e00a54088edc28c8d38e3a34870cc34fb1305b2a98c853dfa8e2b13ca3b2dc061fac3c4ca42326a5f8d40c491c9882c14928b0297a6fbd17ed86e3f78aeb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=44f1bd491d21b3e3fe06273ce11e6530122d7314ec4fa74994ee55481f5133 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf9875d0094449a70e60dd5577ed61d03ae2e86b775aca74bf2723ea6b969c + +handshake=Noise_IX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466695d6599121fe2a7334d2c97732a3ffadbcfd7e6bdb2544697bb5f00916ee3fc981a97e21a035372344bf5ebc58d4530952e0f70491280e937fb043e18e01fb8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=26615f8c05cfc06ba45d92c919ac3646b75c5b98ccc6bf7be435f660303233 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=246f084e1984bada028bdd5706659a090073f4e900983ae7f43938081d0e6c + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f23d888fc466096221d018369dbfd469e8982fe06d5f5403cf73cbae43506d4cb086b2a59e2bb0559d03edd7967de46e777870db5fccba82efee379f4f94d817 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666dbaa36ddf907742a80f1551f8b7d380adbf8039ff57bf43ffe5f1c2315cacaa000b86e59b363dacc8df47185202e71703a31598ae5f209900b544b0987af1b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ba368d3ceaeb7b4ddea9fa0ec3f6af47bce36ec342a0be54a2bd08e7b57a31 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=003d182934bbbfb5ba808d6e335bf7d155504ae7a7d5f5288d2af34bb05e08 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254730f4c1d260b464346081cd7e638a961153cb165f87bd25c9b26c250e5bb8808adf190271445d27f405095fbc3ca27432bdcd0313238417d7c0ce916683bfc8b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466129a73114e12a289af04ec9af3e8a49cfc343ba36ce522267a3eedb9971791a64831f0ac2613dc6820e61293eb7baff3ff9eba1ad801121c6ba483dc43bda464 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96efc6df0548c32e43ca4c59eeb2559626095079ecb0ba2be9c8fd6628d844 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f9e72631a890074a8b30f623968e914862330f34ec4e2aa36f6f7b987a3d6 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254336c06ececc68c95a721a5e1108b1d2c29397707cbf738e7a8849fd2ff08d6298b3f30233695772355e7b3ade8dbffbf41c5cc96f06413594b6659405f516a29 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846691aaca91f9159a9bd67aa886e00a54088edc28c8d38e3a34870cc34fb1305b2a1e81847f6b95142f0026a5496a0cb373b7224ba5692bc0abfa9eec46109c87a6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=44f1bd491d21b3e3fe06273ce11e6530122d7314ec4fa74994ee55481f5133 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf9875d0094449a70e60dd5577ed61d03ae2e86b775aca74bf2723ea6b969c + +handshake=Noise_IX_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466695d6599121fe2a7334d2c97732a3ffadbcfd7e6bdb2544697bb5f00916ee3fcda75b86dcdcf6cc8b4e52dd9265dc2aa7b5773f45de6318af93ff0f4c52d30c8278d3298434c05beadb4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=26615f8c05cfc06ba45d92c919ac3646b75c5b98ccc6bf7be435f660303233 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=246f084e1984bada028bdd5706659a090073f4e900983ae7f43938081d0e6c + +handshake=Noise_IXpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f23d888fc466096221d018369dbfd469e8982fe06d5f5403cf73cbae43506d4cb086b2a59e2bb0559d03edd7967de46e7559f6ca4f3be7e578e57882e381692562156135cf8c334308f6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666dbaa36ddf907742a80f1551f8b7d380adbf8039ff57bf43ffe5f1c2315caca12ad93e06bd127bda9ad1020b877118ef797d76ea657debdad897fcbc0953710f13696878e2c1a2869a0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ba368d3ceaeb7b4ddea9fa0ec3f6af47bce36ec342a0be54a2bd08e7b57a31 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=003d182934bbbfb5ba808d6e335bf7d155504ae7a7d5f5288d2af34bb05e08 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254730f4c1d260b464346081cd7e638a961153cb165f87bd25c9b26c250e5bb8808adf190271445d27f405095fbc3ca2743431211b554223603a05ef4b04acb4fe69dc9d150400ad9c28cfc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466129a73114e12a289af04ec9af3e8a49cfc343ba36ce522267a3eedb9971791a621701ef5f70366820249aa58206ec5179f704ccf6c61778c12e34b86cd99e8c7f6ec4cd08217427f2b2b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=96efc6df0548c32e43ca4c59eeb2559626095079ecb0ba2be9c8fd6628d844 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6f9e72631a890074a8b30f623968e914862330f34ec4e2aa36f6f7b987a3d6 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254336c06ececc68c95a721a5e1108b1d2c29397707cbf738e7a8849fd2ff08d6298b3f30233695772355e7b3ade8dbffbfc719b81dc74cf888722001f7c5dba307a6158a32b4636f5810dc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846691aaca91f9159a9bd67aa886e00a54088edc28c8d38e3a34870cc34fb1305b2a0e75e6be1bec100d6573dcea97d99441a42326a5f8d40c491c9835c2d1f6e87f227b143834e678763257 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=44f1bd491d21b3e3fe06273ce11e6530122d7314ec4fa74994ee55481f5133 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=bf9875d0094449a70e60dd5577ed61d03ae2e86b775aca74bf2723ea6b969c + +handshake=Noise_N_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625481e3638895f74c7f2fb79478a8b1ef0b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=94858a8929ec3029eee24ac3b9430a0ad960324b465ebf1e4a4e5b42d5578d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d950d3e8b3b1c1e92f0672fa29e408ff3051ceb7ab03a61419559a6772f08 + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625464629b177388333c8d175896ab297935 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=33da6aeec7478a08f7878c62fd7fcc88165cf1bf47953546ac1b64fb183258 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3376b3ceedfdeaf78df87cfaeabbe7a3b4cb1ffb9ee72b05a36aaa4fea99ee + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625450b0f423d7d637d7a460b86a48cc487b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e33fa900c0dcebe93bce0408696d13866c780766f0c670a3932b0d05c1c69b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c06aac8a526a8b995fafc59f9ffe856c8316d9fd97db9ba322bd4dbc940158 + +handshake=Noise_N_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548d5c068cc55c86ec3234b490d40afc4cf4d6263378881c946d7f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=94858a8929ec3029eee24ac3b9430a0ad960324b465ebf1e4a4e5b42d5578d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d950d3e8b3b1c1e92f0672fa29e408ff3051ceb7ab03a61419559a6772f08 + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f8dbb976f32d75fe4f1fdd32667b33832835533005266a53712b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=33da6aeec7478a08f7878c62fd7fcc88165cf1bf47953546ac1b64fb183258 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3376b3ceedfdeaf78df87cfaeabbe7a3b4cb1ffb9ee72b05a36aaa4fea99ee + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254354f2847f89991ee82660859ba99e38c0b65beffa762a956db43 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e33fa900c0dcebe93bce0408696d13866c780766f0c670a3932b0d05c1c69b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c06aac8a526a8b995fafc59f9ffe856c8316d9fd97db9ba322bd4dbc940158 + +handshake=Noise_N_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dc989d32c66a940d8f3bb092ec1cc39b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=94858a8929ec3029eee24ac3b9430a0ad960324b465ebf1e4a4e5b42d5578d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d950d3e8b3b1c1e92f0672fa29e408ff3051ceb7ab03a61419559a6772f08 + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254adb2ef9e38153b82ab826cf2c293d2e2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=33da6aeec7478a08f7878c62fd7fcc88165cf1bf47953546ac1b64fb183258 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3376b3ceedfdeaf78df87cfaeabbe7a3b4cb1ffb9ee72b05a36aaa4fea99ee + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d8a9ac9ddfea0fd3f61053e5cce9c468 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e33fa900c0dcebe93bce0408696d13866c780766f0c670a3932b0d05c1c69b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c06aac8a526a8b995fafc59f9ffe856c8316d9fd97db9ba322bd4dbc940158 + +handshake=Noise_N_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548d5c068cc55c86ec32343e3869720328a5659aa70ee82a7e2153 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=94858a8929ec3029eee24ac3b9430a0ad960324b465ebf1e4a4e5b42d5578d +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d950d3e8b3b1c1e92f0672fa29e408ff3051ceb7ab03a61419559a6772f08 + +handshake=Noise_Npsk0_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f8dbb976f32d75fe4f1fcbe700b9013b07745aafab8bf4e2fa7b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=33da6aeec7478a08f7878c62fd7fcc88165cf1bf47953546ac1b64fb183258 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3376b3ceedfdeaf78df87cfaeabbe7a3b4cb1ffb9ee72b05a36aaa4fea99ee + +handshake=Noise_Npsk1_25519_ChaChaPoly_SHA512 +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254354f2847f89991ee82666c5a1d2c330638acc769bec02338bfb4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e33fa900c0dcebe93bce0408696d13866c780766f0c670a3932b0d05c1c69b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=c06aac8a526a8b995fafc59f9ffe856c8316d9fd97db9ba322bd4dbc940158 + +handshake=Noise_K_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6c00a2c6c7b4e047404cd845438f31d +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8f37d99ddd83fcfad851544fadbbd9f83a21cb504f79a040f0db0ef406a2cb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8b69be08bbd320ce82a65b1ac6013f3aada9a0e64e53b0f9de55a83e0fd4e2 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b743993c03a39ed2078fe83cacb0005 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5df379aa748528b394de3a483c10bfa9b2fd420d2d5a7247be18b9b71b1741 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=73a0c4086f45b89ac5ac48564363e3cce8449b2d2c7cf71adadb6258119771 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254af5df3705094e65fd6345071bdb48771 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c63f46ef1a4531b36b6d9d933fc6d97a929ba3fce60a9523228c4df6745d30 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=daa224045edb5559f94be878b2de124313b1e157fa49295925143dca42782b + +handshake=Noise_K_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f0499b194617954a3a80fecc4b0b687b2dcfaca93c170ec8133 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8f37d99ddd83fcfad851544fadbbd9f83a21cb504f79a040f0db0ef406a2cb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8b69be08bbd320ce82a65b1ac6013f3aada9a0e64e53b0f9de55a83e0fd4e2 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549832db195cc1e003857c7f520d021430e9ae20a35b9e906b8f7e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5df379aa748528b394de3a483c10bfa9b2fd420d2d5a7247be18b9b71b1741 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=73a0c4086f45b89ac5ac48564363e3cce8449b2d2c7cf71adadb6258119771 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549ad2b6a5f66290516660e12f3f66ba36a904982d33fe8ed8f15e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c63f46ef1a4531b36b6d9d933fc6d97a929ba3fce60a9523228c4df6745d30 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=daa224045edb5559f94be878b2de124313b1e157fa49295925143dca42782b + +handshake=Noise_K_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fef72b48f3aac25836d9eb5b379c8a5b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8f37d99ddd83fcfad851544fadbbd9f83a21cb504f79a040f0db0ef406a2cb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8b69be08bbd320ce82a65b1ac6013f3aada9a0e64e53b0f9de55a83e0fd4e2 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548ae6fc65d6fc0d280734065c183cc02b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5df379aa748528b394de3a483c10bfa9b2fd420d2d5a7247be18b9b71b1741 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=73a0c4086f45b89ac5ac48564363e3cce8449b2d2c7cf71adadb6258119771 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f13e539dc67cfd7c8bed15eb755b3e70 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c63f46ef1a4531b36b6d9d933fc6d97a929ba3fce60a9523228c4df6745d30 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=daa224045edb5559f94be878b2de124313b1e157fa49295925143dca42782b + +handshake=Noise_K_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f0499b194617954a3a8ba6d2ccb66ba883621b78eb1ccb78060 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=8f37d99ddd83fcfad851544fadbbd9f83a21cb504f79a040f0db0ef406a2cb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8b69be08bbd320ce82a65b1ac6013f3aada9a0e64e53b0f9de55a83e0fd4e2 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549832db195cc1e003857cf56e834a296df1104de185a7b9129a7e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5df379aa748528b394de3a483c10bfa9b2fd420d2d5a7247be18b9b71b1741 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=73a0c4086f45b89ac5ac48564363e3cce8449b2d2c7cf71adadb6258119771 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549ad2b6a5f66290516660fc7bf731ab1516ae6fe1723e6a8fbaeb +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c63f46ef1a4531b36b6d9d933fc6d97a929ba3fce60a9523228c4df6745d30 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=daa224045edb5559f94be878b2de124313b1e157fa49295925143dca42782b + +handshake=Noise_X_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254376c7107f9eb405171d2d1f3d248bce446063fa27b4685471cef3d72d2da8dea4a3e192003851247b8cd95003cccd0c58e96de55d37979fb46e5a502a7e8d6e7 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=95cd22713f4dc63780f443ddf8c584322d1f2e280dae8418c8a526a594e842 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e0f68ed156a13caecfc626ac6ab7516853fd098bc61c56216c95b8d7fc398 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542be0098b3b9dab8f530c810961603ba2f6a822cc78ac7eee268859f4df844553d30e3740165e3ae647bc0b502ee8e56a192bd7a7e255d12c4856c0d56857b688 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c08a79e514742f8589a1ebe18591620d753a930a6f712a8e052fde4f0eee37 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b2515711f8ce760c177220035b0693e0402e8b243720c39c2fa5c63d8fe506 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da919bbbd48942dc8dbb313ccfdf9cbe55ada3842eecc44363f68c7f277f40b9cb22eab3c5e8a67218d9e1d23c7c3b468f6237c9a41c4b7e67549484fb3d2ebc +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5c617be1a77e3328ced09ee748203bbb7afb29b2c84fb20cf3b3a6d638197 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0c7261852346c160ee7df5a37ac9f3bad96737b841a6d544b39f3052e0dddd + +handshake=Noise_X_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254376c7107f9eb405171d2d1f3d248bce446063fa27b4685471cef3d72d2da8dea4a3e192003851247b8cd95003cccd0c552a973c425d8f07f60648804b7601dca1fdf628e900475030723 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=95cd22713f4dc63780f443ddf8c584322d1f2e280dae8418c8a526a594e842 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e0f68ed156a13caecfc626ac6ab7516853fd098bc61c56216c95b8d7fc398 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542be0098b3b9dab8f530c810961603ba2f6a822cc78ac7eee268859f4df844553d30e3740165e3ae647bc0b502ee8e56a81596dfb309c93b19d1534841d06d77ec854aab3070121504346 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c08a79e514742f8589a1ebe18591620d753a930a6f712a8e052fde4f0eee37 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b2515711f8ce760c177220035b0693e0402e8b243720c39c2fa5c63d8fe506 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da919bbbd48942dc8dbb313ccfdf9cbe55ada3842eecc44363f68c7f277f40b9cb22eab3c5e8a67218d9e1d23c7c3b467b9fb8b2dd85bd90458553d745936beb7be4fbadae7aca179b16 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5c617be1a77e3328ced09ee748203bbb7afb29b2c84fb20cf3b3a6d638197 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0c7261852346c160ee7df5a37ac9f3bad96737b841a6d544b39f3052e0dddd + +handshake=Noise_X_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254376c7107f9eb405171d2d1f3d248bce446063fa27b4685471cef3d72d2da8deaa15d6a63c69270eccce4c01bcc449c6fcb8d33e0971f84f0bdd310d557ae81d8 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=95cd22713f4dc63780f443ddf8c584322d1f2e280dae8418c8a526a594e842 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e0f68ed156a13caecfc626ac6ab7516853fd098bc61c56216c95b8d7fc398 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542be0098b3b9dab8f530c810961603ba2f6a822cc78ac7eee268859f4df844553b33f9d2a4423e9a802ff89a058ed672f49301da562d43c4e84803ece0442d767 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c08a79e514742f8589a1ebe18591620d753a930a6f712a8e052fde4f0eee37 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b2515711f8ce760c177220035b0693e0402e8b243720c39c2fa5c63d8fe506 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da919bbbd48942dc8dbb313ccfdf9cbe55ada3842eecc44363f68c7f277f40b92bc84021a9f0cea4dcd51d10b9ddc776d8d7d0db81f5ed7985751fe2e2aea0ec +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5c617be1a77e3328ced09ee748203bbb7afb29b2c84fb20cf3b3a6d638197 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0c7261852346c160ee7df5a37ac9f3bad96737b841a6d544b39f3052e0dddd + +handshake=Noise_X_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254376c7107f9eb405171d2d1f3d248bce446063fa27b4685471cef3d72d2da8deaa15d6a63c69270eccce4c01bcc449c6f52a973c425d8f07f606498675011335ab87e026edc45c947accd +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=95cd22713f4dc63780f443ddf8c584322d1f2e280dae8418c8a526a594e842 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=9e0f68ed156a13caecfc626ac6ab7516853fd098bc61c56216c95b8d7fc398 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542be0098b3b9dab8f530c810961603ba2f6a822cc78ac7eee268859f4df844553b33f9d2a4423e9a802ff89a058ed672f81596dfb309c93b19d158cb77e84c978a3dcb608c6ecac6c2c5d +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c08a79e514742f8589a1ebe18591620d753a930a6f712a8e052fde4f0eee37 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=b2515711f8ce760c177220035b0693e0402e8b243720c39c2fa5c63d8fe506 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_SHA512 +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254da919bbbd48942dc8dbb313ccfdf9cbe55ada3842eecc44363f68c7f277f40b92bc84021a9f0cea4dcd51d10b9ddc7767b9fb8b2dd85bd904585a11cd434469ceca29de06fb9079d0a05 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5c617be1a77e3328ced09ee748203bbb7afb29b2c84fb20cf3b3a6d638197 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0c7261852346c160ee7df5a37ac9f3bad96737b841a6d544b39f3052e0dddd + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664630f67598da3b42143a952be366791b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13d25f218f99a206fea16ec00da9ffa85d826e945ff96cf5c809557d8ac3d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f59ee5daa0c96f469ccbd54f22f1dc6e414db878e9802d9a60bbf66b17c2fa + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545ca945ccbc84a56bec9c401b36132676 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f0eb7ac83b0774a9e2869b41e7740303 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7811d68572ef1cef95b8a84abaa2c04c52c65b6bc7717b20d7d0937fbdd792 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ccf5caaaee5fd10189d055e7c7e73eff5c50c424c5186ba83af5921864b95f + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254eaad96f18f5a9a198b4236625eb25933 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666b172d38e2412c0ae2590dfdbe5e0832 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=627eff0c6f895f05f005ae386f2e3bd0f04a2ce1b308c09a9a7efc24b593d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=57ebc9b6d2d2352741b60d2e221cc05b660997799e0589257dcbaa6ab8a453 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bcc2d28dc4fef41f14c5105e63af938f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846615dfc62d0cb9e27f1e7249fd3bd7a20a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=235d6e8d0ce1821b0a800f12b932240ca563d9246f535102faff2ce267bc2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=454fc5046d2d0b78b7b7bf94edd69a124fc244e9ddc61f8991051192723e34 + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c86b9a678485762fc7a4f979bbd9953460114cd3b560182ebd35 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13d25f218f99a206fea16ec00da9ffa85d826e945ff96cf5c809557d8ac3d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f59ee5daa0c96f469ccbd54f22f1dc6e414db878e9802d9a60bbf66b17c2fa + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544291e8e0931ad8b16a789c6570707bcf7b224b7690859f627dfb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466871d4367360b3a22ef391c1824a2fc2ef48f53b399433fb6ef10 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7811d68572ef1cef95b8a84abaa2c04c52c65b6bc7717b20d7d0937fbdd792 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ccf5caaaee5fd10189d055e7c7e73eff5c50c424c5186ba83af5921864b95f + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546f77e811ab35561749225514a9041dd60f0971cb6c16a595992a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0a44d4d21ef21ccaca66bf95c85c71b4176f2e082084e86f9c1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=627eff0c6f895f05f005ae386f2e3bd0f04a2ce1b308c09a9a7efc24b593d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=57ebc9b6d2d2352741b60d2e221cc05b660997799e0589257dcbaa6ab8a453 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254224ae179b2e475df7ec45848ad251c75c093fdcb0eccb715accb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661ce2f4a22491191e59e782267d686152bb0931d0d95282be7d62 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=235d6e8d0ce1821b0a800f12b932240ca563d9246f535102faff2ce267bc2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=454fc5046d2d0b78b7b7bf94edd69a124fc244e9ddc61f8991051192723e34 + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a632ac4e20596b74a3ba081cade4076b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13d25f218f99a206fea16ec00da9ffa85d826e945ff96cf5c809557d8ac3d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f59ee5daa0c96f469ccbd54f22f1dc6e414db878e9802d9a60bbf66b17c2fa + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b06ef00a4d70a332e9d2d7ee208915d8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a69b59729468a7560df3f44a73e23793 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7811d68572ef1cef95b8a84abaa2c04c52c65b6bc7717b20d7d0937fbdd792 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ccf5caaaee5fd10189d055e7c7e73eff5c50c424c5186ba83af5921864b95f + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce1d92d2350fbee302be9be3ad3c64da +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fa472236809ef20090d9cdcddcf53b3f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=627eff0c6f895f05f005ae386f2e3bd0f04a2ce1b308c09a9a7efc24b593d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=57ebc9b6d2d2352741b60d2e221cc05b660997799e0589257dcbaa6ab8a453 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545d25ad5a9ff63b9a03b1283e53ee3b47 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660d15867c6e1e33cb806e7213c2070fb2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=235d6e8d0ce1821b0a800f12b932240ca563d9246f535102faff2ce267bc2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=454fc5046d2d0b78b7b7bf94edd69a124fc244e9ddc61f8991051192723e34 + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c86b9a678485762fc7a42265d67a1ab87c705687b414166c9df1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=13d25f218f99a206fea16ec00da9ffa85d826e945ff96cf5c809557d8ac3d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f59ee5daa0c96f469ccbd54f22f1dc6e414db878e9802d9a60bbf66b17c2fa + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544291e8e0931ad8b16a78a94b1c635dbd71a5ac125379e105b3de +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466871d4367360b3a22ef39d1de21e1ff59b1753271ca93e5511e28 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=7811d68572ef1cef95b8a84abaa2c04c52c65b6bc7717b20d7d0937fbdd792 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ccf5caaaee5fd10189d055e7c7e73eff5c50c424c5186ba83af5921864b95f + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546f77e811ab355617492204d2720b9e3cf1b1aec5da0fcaa6bf91 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0a44d4d21ef21ccaca686386a2bf51e7354e7af59917d9b6643 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=627eff0c6f895f05f005ae386f2e3bd0f04a2ce1b308c09a9a7efc24b593d5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=57ebc9b6d2d2352741b60d2e221cc05b660997799e0589257dcbaa6ab8a453 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2b +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254224ae179b2e475df7ec4a184c97251967b804a044fdfd2aea7d6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661ce2f4a22491191e59e7076f9aedbd9c6be1c26f94ef4491cd5a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=235d6e8d0ce1821b0a800f12b932240ca563d9246f535102faff2ce267bc2d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=454fc5046d2d0b78b7b7bf94edd69a124fc244e9ddc61f8991051192723e34 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a2f457bc3aff4cffba8148122b472e8d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c096947fe48821afe851ee5ab92bb0df988463d57ba4b283ec431ff8661cd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=75bc0377d0436cff22226d1136c0690df2727247cc08bcb1bacd5515bc0b03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625405d8c5acffb92564fbf7452d9342b1f2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846612a034b4785dad8a1de7e4ef2d8db776 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84e4d0e9a8d546be134bd8d93e6d4ef9fe83b7fc8503ed1d6a3495db3a35b6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae361ebb5e7ae9d1fdad4c00b920379f19fca1eb3997bcccda85a6308b47bd + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c1ea9f3ccd34beeeaa8e540bc7eb9f54 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466efd17f977051f84913f28c6129853611 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e5ccaaeb804ee27f31fb09b68d42fe6b940367fcb4f3591d2fd82b72024edc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afd726057fe1cb681ee905558ed76fbe22239fcbcf8f39970d6ad48ab4f51 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544d5cff5d8b30c51e9adc0b19105c1313 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846687e6f622354e5f80d7cef534378f3090 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e33a92b005c91179ff2a9f0e179b0c972f9b388541bd5c62c379cc05d0ec80 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e73a4ead0be8bd5e1dac776d7d88f6bda655f69da442b99ba0742dc5905d57 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692e0f0cadb3c591903a8bf99a59da7cf9db265b8ae6b75dc23da +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c096947fe48821afe851ee5ab92bb0df988463d57ba4b283ec431ff8661cd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=75bc0377d0436cff22226d1136c0690df2727247cc08bcb1bacd5515bc0b03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c50efd8dcd4dc214c8054a27dc861e4fd0b7593e07254b0ee129 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ccf4b6474627f408499a1bbe8979e087d3029557416e4804d234 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84e4d0e9a8d546be134bd8d93e6d4ef9fe83b7fc8503ed1d6a3495db3a35b6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae361ebb5e7ae9d1fdad4c00b920379f19fca1eb3997bcccda85a6308b47bd + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b869eb72ca64cc2d6827db97a739536c13cbabd38989507992b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663fe7d7cee5f0380f6c801eab927dd4639ffd11e2c2bcb2e9e4b1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e5ccaaeb804ee27f31fb09b68d42fe6b940367fcb4f3591d2fd82b72024edc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afd726057fe1cb681ee905558ed76fbe22239fcbcf8f39970d6ad48ab4f51 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625421ec5b7f100436755fcc7344c07f39d3b204fcb238e868e30f8f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645e9ac3e449c0f53b6793b6526cdfa0d8960b745aa88cb98b4c1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e33a92b005c91179ff2a9f0e179b0c972f9b388541bd5c62c379cc05d0ec80 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e73a4ead0be8bd5e1dac776d7d88f6bda655f69da442b99ba0742dc5905d57 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d1ac871da6795cd1bf42f6e4778eba0e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c096947fe48821afe851ee5ab92bb0df988463d57ba4b283ec431ff8661cd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=75bc0377d0436cff22226d1136c0690df2727247cc08bcb1bacd5515bc0b03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625476ee8d7f3a1828d84dcbf1fcc8a4a2af +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662f8bb2f6eb8e944455239c3883d5baa9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84e4d0e9a8d546be134bd8d93e6d4ef9fe83b7fc8503ed1d6a3495db3a35b6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae361ebb5e7ae9d1fdad4c00b920379f19fca1eb3997bcccda85a6308b47bd + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254044d66fd5be6f6f903529a08c91ca7a8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b28a402e90013fb224a3cdc6885ab50e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e5ccaaeb804ee27f31fb09b68d42fe6b940367fcb4f3591d2fd82b72024edc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afd726057fe1cb681ee905558ed76fbe22239fcbcf8f39970d6ad48ab4f51 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f48976f8e36a771ae749f67142338313 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466110f04a5d3f770028208831ad8973e78 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e33a92b005c91179ff2a9f0e179b0c972f9b388541bd5c62c379cc05d0ec80 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e73a4ead0be8bd5e1dac776d7d88f6bda655f69da442b99ba0742dc5905d57 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846692e0f0cadb3c591903a8ddab209d656baadf356263026a58bd22 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c096947fe48821afe851ee5ab92bb0df988463d57ba4b283ec431ff8661cd0 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=75bc0377d0436cff22226d1136c0690df2727247cc08bcb1bacd5515bc0b03 + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c50efd8dcd4dc214c805058c30240a610132a8a3910453e655d5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ccf4b6474627f408499acbcf8ca41dedf91ee38353404982353a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=84e4d0e9a8d546be134bd8d93e6d4ef9fe83b7fc8503ed1d6a3495db3a35b6 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae361ebb5e7ae9d1fdad4c00b920379f19fca1eb3997bcccda85a6308b47bd + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545b869eb72ca64cc2d682cb6669a21f17801f9ae01c063e4ddc66 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663fe7d7cee5f0380f6c8054b28c1be92664a53099215dd224c2a6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e5ccaaeb804ee27f31fb09b68d42fe6b940367fcb4f3591d2fd82b72024edc +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afd726057fe1cb681ee905558ed76fbe22239fcbcf8f39970d6ad48ab4f51 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625421ec5b7f100436755fcc5821bb3b0e9440da589fba503939929d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645e9ac3e449c0f53b6793ad3c38088fe2a9a1687817650d29825 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e33a92b005c91179ff2a9f0e179b0c972f9b388541bd5c62c379cc05d0ec80 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e73a4ead0be8bd5e1dac776d7d88f6bda655f69da442b99ba0742dc5905d57 + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c6e796fa47f064296ace520223eb1dd4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846676512fffc7284353c50e8f1e50b945fb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=02e58bb367d2215eee3ce2e3a92143cab6b06f86312014629c8eba7d0e38e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0ba20925776dbb39ccd4cdce82047b8d60db1ffc2f0acad621ef0d9009aca0 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547760d42a506aaa5170e068f630688a53 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664ff57dc460faf9957ccc215c82625f72 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=815fb4a13763ec1687575d026446fb266cc4559a2e093563cd567c1928f829 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef3d9cab1bedc9b8c09ecc5d236462d60fd9a9422e8784d32f31ab27ca422e + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542c3389c93d1cbbd6c6f019414066af3e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664893d38851f50347bf1ce3de9524655f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=110a8f74722cb3993b524fb420736083bf5289a21c683b579810d9109d5c9b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22b76dbeef407b045457a05be6485cc69046d41ddfc4cf527be814ff661dbd + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254faa23cff30269a31a11f5b42c9162604 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e9b51f8946c2ae367b2d20ce054ef95e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=09fe0a7fa8ec12cf6456d2d0a55b78880b6ee9334179cedf36b8216b0b179b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e79a394c1e746f3dae6a5f2cb32ca5a20604059585ebb6c339012c9de90641 + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c81819c82320a3cf8a849bd2e79390bde13b992be00ca8465386 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661a77bcc3ed425db85bd9597b6a0d34435d1010cb1b0a3d984f96 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=02e58bb367d2215eee3ce2e3a92143cab6b06f86312014629c8eba7d0e38e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0ba20925776dbb39ccd4cdce82047b8d60db1ffc2f0acad621ef0d9009aca0 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ef2398290ba5d346eb19be574fc6ccce0965514c9aa58262d397 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663b5e2c4787084bef7e3a09ee94b7c2173313452ed41413a3efa1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=815fb4a13763ec1687575d026446fb266cc4559a2e093563cd567c1928f829 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef3d9cab1bedc9b8c09ecc5d236462d60fd9a9422e8784d32f31ab27ca422e + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437705fd6001f9d8fcdd2add594d12af9de7abea9a566426838ca +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666af1d6140fb3e3cd79fa80d74125e9148a2fae4a01fa69759c41 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=110a8f74722cb3993b524fb420736083bf5289a21c683b579810d9109d5c9b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22b76dbeef407b045457a05be6485cc69046d41ddfc4cf527be814ff661dbd + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542990e960017d439237f507eb9a110ea1c15cd1961db0eee83129 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633b80c1088b1489016fc9f7b244968820f26c348bc378f826c69 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=09fe0a7fa8ec12cf6456d2d0a55b78880b6ee9334179cedf36b8216b0b179b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e79a394c1e746f3dae6a5f2cb32ca5a20604059585ebb6c339012c9de90641 + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625459b23e6596ccfc1d861e44965c248bc3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f16a3ac5548d7e8b622e26baf3f256a1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=02e58bb367d2215eee3ce2e3a92143cab6b06f86312014629c8eba7d0e38e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0ba20925776dbb39ccd4cdce82047b8d60db1ffc2f0acad621ef0d9009aca0 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541bc20995406cf070cdbd007ba8de8fc3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666fff7b379bd0814d6ab0f7d1cdf32e59 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=815fb4a13763ec1687575d026446fb266cc4559a2e093563cd567c1928f829 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef3d9cab1bedc9b8c09ecc5d236462d60fd9a9422e8784d32f31ab27ca422e + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254526352a52eb702c0846d41e845f956e6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665d3bcbb1d75f8239e7dd48fd00e023ba +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=110a8f74722cb3993b524fb420736083bf5289a21c683b579810d9109d5c9b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22b76dbeef407b045457a05be6485cc69046d41ddfc4cf527be814ff661dbd + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540c54a88750132ccc7d2606ccd647e158 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b5570e4eb7f95e64466aa037c73e745e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=09fe0a7fa8ec12cf6456d2d0a55b78880b6ee9334179cedf36b8216b0b179b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e79a394c1e746f3dae6a5f2cb32ca5a20604059585ebb6c339012c9de90641 + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c81819c82320a3cf8a848138f5e224a7535afb46defe7d87553c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661a77bcc3ed425db85bd942db11c4661841c59bc54d0800472873 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=02e58bb367d2215eee3ce2e3a92143cab6b06f86312014629c8eba7d0e38e5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0ba20925776dbb39ccd4cdce82047b8d60db1ffc2f0acad621ef0d9009aca0 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ef2398290ba5d346eb19c7fc80387a124bee9c89251344667fc0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663b5e2c4787084bef7e3a6061d1819ecd024f00bf02c2e6acf677 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=815fb4a13763ec1687575d026446fb266cc4559a2e093563cd567c1928f829 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef3d9cab1bedc9b8c09ecc5d236462d60fd9a9422e8784d32f31ab27ca422e + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625437705fd6001f9d8fcdd2730a8aedfe5a4471d07b97371d534f57 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666af1d6140fb3e3cd79fa4642e8c5891b3c04a8128d5f3cd3a845 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=110a8f74722cb3993b524fb420736083bf5289a21c683b579810d9109d5c9b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22b76dbeef407b045457a05be6485cc69046d41ddfc4cf527be814ff661dbd + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542990e960017d439237f52c524921d226d4977c7c5f80fe55e3c7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633b80c1088b1489016fceccf88e99c39eb84390e2d6c09747f91 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=09fe0a7fa8ec12cf6456d2d0a55b78880b6ee9334179cedf36b8216b0b179b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=e79a394c1e746f3dae6a5f2cb32ca5a20604059585ebb6c339012c9de90641 + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540add9701c614f83639fc5b8469a824e1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466adae6f9cdefe2c94ee03225c37604b0a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3dc2f873e6658db54bb9c572f74b4c1cf45ad75c65239938a138836f952884 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e3bc17a298d558e3a06e40efb7b7fb5c96c4aa1d5e4d5f787d2515e14b998 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546610e2230ff1f3183d48afe4781ff0f6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466727d1d82190773d3282167eb6e957f08 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c270a853bd1c257e47c627efd4b79e3530ba09c1d52d5b17a2b3692c1f1c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae75589da7fee8dd69c1b09e67a2c1f7e6eacaee8014dd93276961df209a42 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fef2b62435793bda6a4c4aad05ae8b4a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667b3cb7dfdc05036e035075c3154d5f32 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe3643f10e3112865a008a1c5c10c54896ca6d88c8d90914f94dd6fac138cd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=403d08bf236b73390ed2923cd3c1ff651185bbe29b564d2cb40a4675b6cbfc + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546dec2771909ce9080044dd47d7e2ba76 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846619249b3f50f0f8542659ce99e21cb636 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=30f5556b007aaf32d4952968082ba5217423797071e81cdd569b73a8725017 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2dc14afd5ebf1485e853ba62a6180a64707caa20165712e8d495c8c603e97f + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c28485b9d3a6a7ca1e70af530f049309a3b19da102d864d1599 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846626c79bad0b5abe023979c227b9eb46738a33dbc12faa4ab64df0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3dc2f873e6658db54bb9c572f74b4c1cf45ad75c65239938a138836f952884 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e3bc17a298d558e3a06e40efb7b7fb5c96c4aa1d5e4d5f787d2515e14b998 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c643b3d339ed91764914480f545d04a1cdf9982ed7e7e1286a7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466418f1875550e6432799a2eb9a92fcb4fc53bad4bb8aa1dc3f3ca +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c270a853bd1c257e47c627efd4b79e3530ba09c1d52d5b17a2b3692c1f1c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae75589da7fee8dd69c1b09e67a2c1f7e6eacaee8014dd93276961df209a42 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545e50e3aef221429fa8e8134dcc000d3ce8f0a959f9b5cc273dbc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665a65999701c16a9ae50ffe150f59674b235dcf3a3d6ea1d5d91f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe3643f10e3112865a008a1c5c10c54896ca6d88c8d90914f94dd6fac138cd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=403d08bf236b73390ed2923cd3c1ff651185bbe29b564d2cb40a4675b6cbfc + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ea662b9896170d9582a6150ca6343873bc78f15cbd3060355e29 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666c2eeab8af4a3f66ba3d1a3e4b4acc9f606878c661b2ba31a4ec +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=30f5556b007aaf32d4952968082ba5217423797071e81cdd569b73a8725017 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2dc14afd5ebf1485e853ba62a6180a64707caa20165712e8d495c8c603e97f + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e047c5ed566988814daa1e9e4605341 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664938a09e1060496bb538cb5f75115a31 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3dc2f873e6658db54bb9c572f74b4c1cf45ad75c65239938a138836f952884 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e3bc17a298d558e3a06e40efb7b7fb5c96c4aa1d5e4d5f787d2515e14b998 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545df1c569503f51071bdf5cd13746f1f6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660fb79e8c546d18b5aedcec17dd1b7ae3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c270a853bd1c257e47c627efd4b79e3530ba09c1d52d5b17a2b3692c1f1c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae75589da7fee8dd69c1b09e67a2c1f7e6eacaee8014dd93276961df209a42 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254edd4fe26947e07493993cad56c107e29 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662480512f17f4dda812ba7e8c02b84333 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe3643f10e3112865a008a1c5c10c54896ca6d88c8d90914f94dd6fac138cd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=403d08bf236b73390ed2923cd3c1ff651185bbe29b564d2cb40a4675b6cbfc + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b2d96179cc834d3bf1192c8cd4e7c1f0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846624d094f7cde5f0b1561205f0a58cb4e1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=30f5556b007aaf32d4952968082ba5217423797071e81cdd569b73a8725017 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2dc14afd5ebf1485e853ba62a6180a64707caa20165712e8d495c8c603e97f + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c28485b9d3a6a7ca1e7ae04c80a14d382f1e9a8b3932548ecfa +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846626c79bad0b5abe023979ebedf6784eaba92e4bbc6ade0a638027 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=3dc2f873e6658db54bb9c572f74b4c1cf45ad75c65239938a138836f952884 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8e3bc17a298d558e3a06e40efb7b7fb5c96c4aa1d5e4d5f787d2515e14b998 + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c643b3d339ed91764918cbf74d28fc8719e73556b95fb8700c3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466418f1875550e6432799a6d7ab709f63bdae8d6d2c952226eb8e2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c270a853bd1c257e47c627efd4b79e3530ba09c1d52d5b17a2b3692c1f1c7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ae75589da7fee8dd69c1b09e67a2c1f7e6eacaee8014dd93276961df209a42 + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545e50e3aef221429fa8e881b96f072d239b26dfd0155e0757eda9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665a65999701c16a9ae50fd52f26c48089f42e1c84202264bba4d3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=fe3643f10e3112865a008a1c5c10c54896ca6d88c8d90914f94dd6fac138cd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=403d08bf236b73390ed2923cd3c1ff651185bbe29b564d2cb40a4675b6cbfc + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ea662b9896170d9582a69f28efbf005006e6d922df48806ea391 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666c2eeab8af4a3f66ba3df608254030f07adb8a353054b309566a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=30f5556b007aaf32d4952968082ba5217423797071e81cdd569b73a8725017 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2dc14afd5ebf1485e853ba62a6180a64707caa20165712e8d495c8c603e97f + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661001bf5d654afd000b60a48982a7f8f16bad1946aefa20866c7c142a94c472233b64ed63dfc7555c854c43e68cd95f6d1475061fe795ea1e30f1cf6d8077235a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9e79f9d8263bcf07bbcc8e8729039c8cce829d3be34aa7f1414aef1312e2e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cb46d49add7c73f9a1bc9c2bb015e114ff3c23aaff62326cd077f3d54d3d8d + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d1cb2f10981522e83aae2312213c754f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665fd1624f32ed036ff7fc7f8c27ff605eba031dca8f50f0750e420763654f319c02737a43b9d5d56fd312fbd3e875bf695b546491b9a5d4f0a3866dd74079bdc1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9057ac2b936c434d8bd9a5f926136918b98c36c73d65ae6e092509dc0f7d1d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6434f211fcaa13b60694f51d53bd2d058231706b393d76016e6fb18500796a + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544f135b82ef3c887c3a1f13fa66bdd6ff +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6f1bac5db9338604250bf5aea410705dab380ac8d53e05070aa26bd4e8adba93f296cffaa1f2ed206645b81e91e706bbcfd9abe7465b3eed22b53984a1dac07 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2681c5a5a71b1a764618ffe8265b55b0262a8dc0e579ea417b506565587609 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b512c5f3481260755d59236bcf47d03b49096fbfb58f4f01d3e57e93aa8a80 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e5854b1e81cbb8cc49dc98173b9cefd0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466492d0eb95d7c0b7d7e02e0057dab75d823438caf0ca19e7b8f550466c9e5ec10c36f9e3ab39e90ce475d2ce2f81d912655d8d21d8ee3c26ca6111bb3bdc449e0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=87c279f5b3cab2d36d5d53adfef24f41f8f0ad59541d80cfeb3d32a9373ab4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=163c5ca8ea00dd3b81b2b494e038ad57c26277be9a54efbf0b491eb34621ea + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661001bf5d654afd000b60a48982a7f8f16bad1946aefa20866c7c142a94c47223b18e3f707c460fbaa28865ad9d668ea9abda0084c02e273674c44fe10712a87cf1f039a7c62b617178f0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9e79f9d8263bcf07bbcc8e8729039c8cce829d3be34aa7f1414aef1312e2e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cb46d49add7c73f9a1bc9c2bb015e114ff3c23aaff62326cd077f3d54d3d8d + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447633918cf073418422f340bfd1bc8db323c006435cbeb4e766f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665fd1624f32ed036ff7fc7f8c27ff605eba031dca8f50f0750e420763654f319c306334979630201ed10c494d6e98c7599c97ed31e367ab91ae6752af9d3e7f0f310b1a68839b57f3af4b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9057ac2b936c434d8bd9a5f926136918b98c36c73d65ae6e092509dc0f7d1d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6434f211fcaa13b60694f51d53bd2d058231706b393d76016e6fb18500796a + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254feeb1e12496f2e4e099574f80191ac09276f3f7e5e523e91eb01 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6f1bac5db9338604250bf5aea410705dab380ac8d53e05070aa26bd4e8adba9725f545c2be3115608bd82e9ecc664e335683343957a81560b3c30b947654f0cf1b4d8a7f75fe3b6766e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2681c5a5a71b1a764618ffe8265b55b0262a8dc0e579ea417b506565587609 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b512c5f3481260755d59236bcf47d03b49096fbfb58f4f01d3e57e93aa8a80 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548c01fe1c6c49957de78d150a12bc0a4299e0fce95818fcf28e50 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466492d0eb95d7c0b7d7e02e0057dab75d823438caf0ca19e7b8f550466c9e5ec1064d3270ff07b4c418f9960259ec303f31e374382eb37dddd0343063ec69b9f6a1cb2126f82a678d8b5fa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=87c279f5b3cab2d36d5d53adfef24f41f8f0ad59541d80cfeb3d32a9373ab4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=163c5ca8ea00dd3b81b2b494e038ad57c26277be9a54efbf0b491eb34621ea + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661001bf5d654afd000b60a48982a7f8f16bad1946aefa20866c7c142a94c47223332bc232984079635e54eb96a835e148dc8d60cae839375194f9c7b0ddc8c951 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9e79f9d8263bcf07bbcc8e8729039c8cce829d3be34aa7f1414aef1312e2e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cb46d49add7c73f9a1bc9c2bb015e114ff3c23aaff62326cd077f3d54d3d8d + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545276316a0ed49eab2fa9c4d911322382 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665fd1624f32ed036ff7fc7f8c27ff605eba031dca8f50f0750e420763654f319c3ca35ccf8d081dd3bc901f4a5d13c8f683208c9cd51ac4c469753652411a6a2b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9057ac2b936c434d8bd9a5f926136918b98c36c73d65ae6e092509dc0f7d1d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6434f211fcaa13b60694f51d53bd2d058231706b393d76016e6fb18500796a + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254043225c8bd9663ef3ef17c4f3a01688a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6f1bac5db9338604250bf5aea410705dab380ac8d53e05070aa26bd4e8adba90e3e28528791e262d6447fc135a62b6ef174eca6f83586e29efebf0d211d6c17 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2681c5a5a71b1a764618ffe8265b55b0262a8dc0e579ea417b506565587609 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b512c5f3481260755d59236bcf47d03b49096fbfb58f4f01d3e57e93aa8a80 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549f846d3cf079683dacbc4b63ad6c0a01 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466492d0eb95d7c0b7d7e02e0057dab75d823438caf0ca19e7b8f550466c9e5ec10dcff0ef61dd99720eed6968a3a5f9ebc124df4a7e622f4aaa27dbf6803ab23d4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=87c279f5b3cab2d36d5d53adfef24f41f8f0ad59541d80cfeb3d32a9373ab4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=163c5ca8ea00dd3b81b2b494e038ad57c26277be9a54efbf0b491eb34621ea + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661001bf5d654afd000b60a48982a7f8f16bad1946aefa20866c7c142a94c47223888ddf72adf7001627f8ed91dd333d25abda0084c02e273674c4f5a1c2f6bc0ba9c95969fa9346fbaf1f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9e79f9d8263bcf07bbcc8e8729039c8cce829d3be34aa7f1414aef1312e2e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cb46d49add7c73f9a1bc9c2bb015e114ff3c23aaff62326cd077f3d54d3d8d + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625447633918cf073418422f4e800c64262116b557756d3917dea3b0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665fd1624f32ed036ff7fc7f8c27ff605eba031dca8f50f0750e420763654f319c22fc74d15ca64b517e5b7d93d4786c339c97ed31e367ab91ae6763a0ae92a90d8db97f341fa0af4b2922 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=9057ac2b936c434d8bd9a5f926136918b98c36c73d65ae6e092509dc0f7d1d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=6434f211fcaa13b60694f51d53bd2d058231706b393d76016e6fb18500796a + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254feeb1e12496f2e4e0995be8115bad42c6477a3b1b28252a81fbe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6f1bac5db9338604250bf5aea410705dab380ac8d53e05070aa26bd4e8adba9259737628f54586b0c82e86c3d58105635683343957a81560b3c76df030794ccb6677d91b03c63198fed +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2681c5a5a71b1a764618ffe8265b55b0262a8dc0e579ea417b506565587609 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b512c5f3481260755d59236bcf47d03b49096fbfb58f4f01d3e57e93aa8a80 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548c01fe1c6c49957de78d567452df11303abb4e72c68fd934013b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466492d0eb95d7c0b7d7e02e0057dab75d823438caf0ca19e7b8f550466c9e5ec1089cb6312ea00184d8e4823521c7542711e374382eb37dddd03434e498cfe49446d13a1f17641c62d74be +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=87c279f5b3cab2d36d5d53adfef24f41f8f0ad59541d80cfeb3d32a9373ab4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=163c5ca8ea00dd3b81b2b494e038ad57c26277be9a54efbf0b491eb34621ea + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466179eeb7aae5b20dec5995bc6a5d6e2bb9ba4230601424a00e6db617861aa71450288e5ec4f28f4623eb6bdb44b3157684d77cd66463f11069c7d976244bc728d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2bb1a0510ab355a2510ff3004b60eca89d1719792c5debfe35e8bacd3a22b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8b38dc71a41266bb63183e45bc3e44f8f57fe720828cbc1296dc6bfc7d2557 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254939dacc481851a259b90b407652ca87c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d3c3067c9805256d1dc3e4270df2edf92b5490b88dfc45ad9d5a48b23d181af0dcad241275390b064c4b453d071f8e4ad6d2515685b25744b80f8e6f4a4abb7c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f7b885d922743399857f09ed19c19ca8a4e74cd85eda575b12444f1fed058f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2686fb37d67ed89179e0b5d0af77792ee6cf1a9b7e169af39512daeb1d20d3 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547062e9cf5576fc2b4c124d9ce66a28a0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668632910f8bae8e626c3c3ee7de1bc07dc38d0186546649ae93933bdc7edb0a65a46196ceff28ba865581ec2563330a8ce8891f325f8a478efc4c955d2eb6a37d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=115fea697d7bcade2ef9a2d597bd4084a517fe809ecc0741ce9dd61c98fb90 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c85e6c4d4331ad8ed2db83a7e9406ac663299046ea7582b1f5e2cc4c7c935d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545d1f4bb51a8be81e03d55eddabf13fbb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669cd62d93703ab4f915f66c4c10b254212de4a53b3d95a63ea962f6d35da0d9542ccb4b9b10b069dfaaf134297079a71db28c4babf29d84b7d8f8227826600fc9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=409d4523fe0934586527baa3e12f1d4f5052096478e56e84c175fcc9b6625f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7d53fd728a2b440653f65a1facc49bcad6ca6e0a78972c4271b8518290c91 + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466179eeb7aae5b20dec5995bc6a5d6e2bb9ba4230601424a00e6db617861aa71457d13eafd308a55b40ab5f394b4a062f11647d7c3399446edcb98c15fd689f9a1130785bb45bb91377c1c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2bb1a0510ab355a2510ff3004b60eca89d1719792c5debfe35e8bacd3a22b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8b38dc71a41266bb63183e45bc3e44f8f57fe720828cbc1296dc6bfc7d2557 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542a49dcf4c8364f330f2c4096746db3b89b22d735da6a239394a2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d3c3067c9805256d1dc3e4270df2edf92b5490b88dfc45ad9d5a48b23d181af0d2bb9743fc882ac69de65ea6a60888a59d4fff629fa819bbff1024925852f1686ee8cf6c72c230c97381 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f7b885d922743399857f09ed19c19ca8a4e74cd85eda575b12444f1fed058f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2686fb37d67ed89179e0b5d0af77792ee6cf1a9b7e169af39512daeb1d20d3 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543a9230768ed98f32a31dd2e8e4ebd76f2e0ca3824a4c211aeda0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668632910f8bae8e626c3c3ee7de1bc07dc38d0186546649ae93933bdc7edb0a651dbc7414ce613441d019292b1c34b8d0c3b6f6d04e36d77d8232f885f117d61218b74ceee4bb683247d0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=115fea697d7bcade2ef9a2d597bd4084a517fe809ecc0741ce9dd61c98fb90 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c85e6c4d4331ad8ed2db83a7e9406ac663299046ea7582b1f5e2cc4c7c935d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545c320f73198c23651d414b71ef96c3edcc0e4e02d78b3359ff30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669cd62d93703ab4f915f66c4c10b254212de4a53b3d95a63ea962f6d35da0d9544a9cb36f29d81bffa4d9168eea4b4d5391296c52ec0585c8deeef0425f8728304a8f10ad563280a2f1d4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=409d4523fe0934586527baa3e12f1d4f5052096478e56e84c175fcc9b6625f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7d53fd728a2b440653f65a1facc49bcad6ca6e0a78972c4271b8518290c91 + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466179eeb7aae5b20dec5995bc6a5d6e2bb9ba4230601424a00e6db617861aa71458e36527aef883c8c96b8f626909171994d85960ab8d14303beb35b5df7204a10 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2bb1a0510ab355a2510ff3004b60eca89d1719792c5debfe35e8bacd3a22b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8b38dc71a41266bb63183e45bc3e44f8f57fe720828cbc1296dc6bfc7d2557 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f39aef73df6fe3c5f28de40ce7f759a0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d3c3067c9805256d1dc3e4270df2edf92b5490b88dfc45ad9d5a48b23d181af05d9187615bf9c1d9b1e5d7779bcee0bdcbb351df0b5b450a6ffcb11a5287109c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f7b885d922743399857f09ed19c19ca8a4e74cd85eda575b12444f1fed058f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2686fb37d67ed89179e0b5d0af77792ee6cf1a9b7e169af39512daeb1d20d3 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f39c39bdeb9989b9352beb67fbb47db0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668632910f8bae8e626c3c3ee7de1bc07dc38d0186546649ae93933bdc7edb0a65c6f3b964c11299306556d0df66e428db049c2698e430f4f642b228c12e8b196d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=115fea697d7bcade2ef9a2d597bd4084a517fe809ecc0741ce9dd61c98fb90 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c85e6c4d4331ad8ed2db83a7e9406ac663299046ea7582b1f5e2cc4c7c935d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625492e67987c1b2adc0152f1442ae64a66d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669cd62d93703ab4f915f66c4c10b254212de4a53b3d95a63ea962f6d35da0d954f1d3d37785abc0bc28d3e37a0d3df4fbcea0bc3b6f47926decd3d4b98ea0990f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=409d4523fe0934586527baa3e12f1d4f5052096478e56e84c175fcc9b6625f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7d53fd728a2b440653f65a1facc49bcad6ca6e0a78972c4271b8518290c91 + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466179eeb7aae5b20dec5995bc6a5d6e2bb9ba4230601424a00e6db617861aa7145dda1510598297081009b0fc99622410c1647d7c3399446edcb98da03e57385e8faac62bdc41eadcecb8b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2bb1a0510ab355a2510ff3004b60eca89d1719792c5debfe35e8bacd3a22b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8b38dc71a41266bb63183e45bc3e44f8f57fe720828cbc1296dc6bfc7d2557 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542a49dcf4c8364f330f2c15d431db17f7b786d48c641fbe6400e2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d3c3067c9805256d1dc3e4270df2edf92b5490b88dfc45ad9d5a48b23d181af0d9b183f5fbd413da83c7c79e1bd427b09d4fff629fa819bbff108d80d0b71ab1d99b7c818456879b06b6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f7b885d922743399857f09ed19c19ca8a4e74cd85eda575b12444f1fed058f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2686fb37d67ed89179e0b5d0af77792ee6cf1a9b7e169af39512daeb1d20d3 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543a9230768ed98f32a31d857e0da9b9145a8da70a019517797d63 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668632910f8bae8e626c3c3ee7de1bc07dc38d0186546649ae93933bdc7edb0a6546e65dee7b9d77f189d5f5fa8ee92552c3b6f6d04e36d77d82327b7f5cb50529fd6b2174e66a7148312f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=115fea697d7bcade2ef9a2d597bd4084a517fe809ecc0741ce9dd61c98fb90 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=c85e6c4d4331ad8ed2db83a7e9406ac663299046ea7582b1f5e2cc4c7c935d + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545c320f73198c23651d417f6af622e2c553d933c8c67756f925b4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669cd62d93703ab4f915f66c4c10b254212de4a53b3d95a63ea962f6d35da0d954aa7c44244e9ce82031d2825a5dcd0c5c91296c52ec0585c8deee38dff35af0421f67c4a806b7f4f49d47 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=409d4523fe0934586527baa3e12f1d4f5052096478e56e84c175fcc9b6625f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7d53fd728a2b440653f65a1facc49bcad6ca6e0a78972c4271b8518290c91 + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660bee8aa990598c582bf25ff21b457e80 +msg_2_payload= +msg_2_ciphertext=291e0f5e79575df990b58e317022d3c6c864164d559dcb77ceb88a02eba2e0a422aa0bc47de0c7b744c10a26b0f4de12ca28ba39eb4266bbe53ef915a869eb69 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f9972897d0a22fd3ab4f7df758c17201e716d92495d7e798597ca633fcfa79 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=663a74b07d26987f1aaea566c63fed3ab905d0549d4cbbba95998087711e7b + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254157c844130c0ac1a8cd295ab5c2863f2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d0ccb8f5058ba0a1fe9e0d072bb75403 +msg_2_payload= +msg_2_ciphertext=dd296759956a201688e8438b5452e3224f22f3ce9a0c57b37a16b930b0dc6ce29ed8196b7ab499814a3cf0cd656a4959302475376a205bb9aee6b4d6d6af5210 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b8f919e1619e002fc009c8201390385e887e9cef040b20b93d6d92525060af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=813ffe58a1028b85472449f2e7612dce5751dcc2ad70d889e91018a148fc69 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625456e86321f5117e2826a5ad00441de277 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662634d4221d0ec8fdda4507d9dcf91e08 +msg_2_payload= +msg_2_ciphertext=3a7a393db716dc075d961ce4109c2af6f7e5dcd35c0b947bf30c01936a6b4b36f1129b52c3bd379d90a216a63b3675a482fb307672a7e95517889addfc1cc0c5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=97f376dd10bbfe09c7570b3514ff97a15fb7d7cefc2b25f5ce5a67dcd1cf67 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9669b636c25732803353c3c1e70508120e8b6896a2fb5edab54f831d162db6 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549b78be66b1f2e09771269003303a25c1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846606fea2bb9b9e69e297b06911a5d0d1c8 +msg_2_payload= +msg_2_ciphertext=f4364f3c48d2280a28b5a0cc4dbbdf75ae5efff3e129e5beff1ea88c7f501b9fd178457c94ad442beb3afa4f915c3ecb6a48f6a0ff1692761575a7903144b8f7 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e6c2fa29df53fe75a34bea7633a930df3aa8c62e20accf544277163022c037 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94ec62cb132c7c7ec8d99d702072fe1f9e1602bdca45023e8d3db9db63237d + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a723d539c7b582ffdf1a53288cadbb26 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669a62c45ef5d3c92b21360e796d4c197a +msg_2_payload= +msg_2_ciphertext=1e9a2da1ec0430295c3b8b7e1888bcb09293f61e62dfbdb29707348a95bdce2904ce827fd5330e814ba2346712de095e110c5aedd3543a74e86afa9d2cab6f83 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9307b428397906f7e529cf6dd1bdf53f782a88f89a250c18dc83d57c9992dd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8b1a7574e6cee466e01ba7f20e6cf372188b6294b43823ebc4c4c8a753b6e0 + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea98bff8eb4696d6d3c0e4f70aba310a675391aaf82e0804fa79 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=291e0f5e79575df990b58e317022d3c6c864164d559dcb77ceb88a02eba2e0a499f907c37ae8e0c3aaffe34553249753254343342ae4704d7c23cd8a77a1807441d2c7501369bb467126 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f9972897d0a22fd3ab4f7df758c17201e716d92495d7e798597ca633fcfa79 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=663a74b07d26987f1aaea566c63fed3ab905d0549d4cbbba95998087711e7b + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae18211db1dcdc553413922091f72d9ced221e2acda5a660f9b7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b660d1ecf94c4595dd57f654d3a0f19cccd9b63570f79de6c96e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=dd296759956a201688e8438b5452e3224f22f3ce9a0c57b37a16b930b0dc6ce2a537ae7c3f8105a2d3205317f8106e9257c07ceb5be90bcae241636ec9f1d1403c7d54fdb497a925991f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b8f919e1619e002fc009c8201390385e887e9cef040b20b93d6d92525060af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=813ffe58a1028b85472449f2e7612dce5751dcc2ad70d889e91018a148fc69 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625467ec45c3d546c1618f39adc8f13e3f35a17f633a753012f9aa29 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a92e7cbd80b059556fffcbb169e97c1bde48cfcac32e1368920f +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3a7a393db716dc075d961ce4109c2af6f7e5dcd35c0b947bf30c01936a6b4b36982e61825971d574332da023645bb288e766c9dbe21f85a458860f34d47d5087b3e701cc52600fa760ce +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=97f376dd10bbfe09c7570b3514ff97a15fb7d7cefc2b25f5ce5a67dcd1cf67 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9669b636c25732803353c3c1e70508120e8b6896a2fb5edab54f831d162db6 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419c32a8d476aa90292e1d2946f42be7dd73161301ecdd5168423 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665c79e23e35136c510c909b68a7bf6508d04d169d772f42b5bc0e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f4364f3c48d2280a28b5a0cc4dbbdf75ae5efff3e129e5beff1ea88c7f501b9f1c3c70937fadc804f6b89718241ae97906d8bfebdb39bfd7b9fe0871270ae98eb13d651ecec51bc2d66e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e6c2fa29df53fe75a34bea7633a930df3aa8c62e20accf544277163022c037 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94ec62cb132c7c7ec8d99d702072fe1f9e1602bdca45023e8d3db9db63237d + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549974e0c1a1b524048c2bab05845477ddee545b9e24a00fa921d8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663070ecf7cc85144673b2911307e9d0e3ed49482c84a7a59d3334 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=1e9a2da1ec0430295c3b8b7e1888bcb09293f61e62dfbdb29707348a95bdce2923776b5ee769a4928746f064091987a2d97a14c5bf5c035f4991be19871e8779eb5a753c6d99be0a20d1 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9307b428397906f7e529cf6dd1bdf53f782a88f89a250c18dc83d57c9992dd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8b1a7574e6cee466e01ba7f20e6cf372188b6294b43823ebc4c4c8a753b6e0 + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ffcf5f753467c7c2b694d4eb00d1baaf +msg_2_payload= +msg_2_ciphertext=291e0f5e79575df990b58e317022d3c6c864164d559dcb77ceb88a02eba2e0a42fb1e938d3fb06653176bc867442b318b3360a8f9ebdc1524fe34b0d01725fc8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f9972897d0a22fd3ab4f7df758c17201e716d92495d7e798597ca633fcfa79 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=663a74b07d26987f1aaea566c63fed3ab905d0549d4cbbba95998087711e7b + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fac3c8bd046a3e9d0b38ccd7698c7db6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665270ac63c46e1a1e26719e5752918e22 +msg_2_payload= +msg_2_ciphertext=dd296759956a201688e8438b5452e3224f22f3ce9a0c57b37a16b930b0dc6ce2d2a1fcad32691cfbd2db34ffb0eb021e5d7f48acb637ce70ed33921ee3ca689f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b8f919e1619e002fc009c8201390385e887e9cef040b20b93d6d92525060af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=813ffe58a1028b85472449f2e7612dce5751dcc2ad70d889e91018a148fc69 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625435b9059703f0f637c4ead9348dc36f16 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669a201926a025f16da73a7cdf456738ce +msg_2_payload= +msg_2_ciphertext=3a7a393db716dc075d961ce4109c2af6f7e5dcd35c0b947bf30c01936a6b4b36a1cd9d2d29d8df1cae8a102e26684ead172e71f633ff50d7d7c573c35152b6c7 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=97f376dd10bbfe09c7570b3514ff97a15fb7d7cefc2b25f5ce5a67dcd1cf67 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9669b636c25732803353c3c1e70508120e8b6896a2fb5edab54f831d162db6 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541da3f1038dde89dca976e36d13d38cb8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661f04fde9d6d3ca84c7f1c7167cb63357 +msg_2_payload= +msg_2_ciphertext=f4364f3c48d2280a28b5a0cc4dbbdf75ae5efff3e129e5beff1ea88c7f501b9fd634eda749f434e721ff28d808524bd37f20a0c93e065a591c9272510869a9e1 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e6c2fa29df53fe75a34bea7633a930df3aa8c62e20accf544277163022c037 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94ec62cb132c7c7ec8d99d702072fe1f9e1602bdca45023e8d3db9db63237d + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254991d7378909ba56f867c5a46cb280527 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b7d7d49c8cdbf29b0e5a7f486c7d774f +msg_2_payload= +msg_2_ciphertext=1e9a2da1ec0430295c3b8b7e1888bcb09293f61e62dfbdb29707348a95bdce29a4fd3c75a1f27bda13b92eeb81995531e73aaf41be201edd340e9decbcce9b42 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9307b428397906f7e529cf6dd1bdf53f782a88f89a250c18dc83d57c9992dd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8b1a7574e6cee466e01ba7f20e6cf372188b6294b43823ebc4c4c8a753b6e0 + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ea98bff8eb4696d6d3c004ce0d42550c2b03ee2612ca6e9eec18 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=291e0f5e79575df990b58e317022d3c6c864164d559dcb77ceb88a02eba2e0a4db2f87efd55abe5bb4ea2f0003a2497c254343342ae4704d7c233e1bd4602b35f158072774208aca6994 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=f9972897d0a22fd3ab4f7df758c17201e716d92495d7e798597ca633fcfa79 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=663a74b07d26987f1aaea566c63fed3ab905d0549d4cbbba95998087711e7b + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae18211db1dcdc55341394577371548dcdaddb6157b5753662ae +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b660d1ecf94c4595dd5712cccfbae9909b1ab004f4f12bff3a33 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=dd296759956a201688e8438b5452e3224f22f3ce9a0c57b37a16b930b0dc6ce298cc5dd18599c844fea755c57ed3c85257c07ceb5be90bcae241fee76d9fbcd17295f12f3fa2ec616528 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=b8f919e1619e002fc009c8201390385e887e9cef040b20b93d6d92525060af +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=813ffe58a1028b85472449f2e7612dce5751dcc2ad70d889e91018a148fc69 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625467ec45c3d546c1618f393067aed902b79b0759bf968282a2c103 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a92e7cbd80b059556fff5b12b14c05770aff36bcc9ebc7ddeee2 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3a7a393db716dc075d961ce4109c2af6f7e5dcd35c0b947bf30c01936a6b4b36dd253a46b8575151d8867881d28453aee766c9dbe21f85a4588624fa9b30ac191ca69a7bfffa584f28a4 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=97f376dd10bbfe09c7570b3514ff97a15fb7d7cefc2b25f5ce5a67dcd1cf67 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9669b636c25732803353c3c1e70508120e8b6896a2fb5edab54f831d162db6 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419c32a8d476aa90292e13801b5d6071e1336ffd6ea151b596406 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665c79e23e35136c510c9085f9ab38ad9a3ad5ef10537e6dc8d07c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f4364f3c48d2280a28b5a0cc4dbbdf75ae5efff3e129e5beff1ea88c7f501b9f3e33f6dfc8d3fe6635968a6600df1d6406d8bfebdb39bfd7b9fed61850abbf511f0095bcb77843c3d61b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e6c2fa29df53fe75a34bea7633a930df3aa8c62e20accf544277163022c037 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=94ec62cb132c7c7ec8d99d702072fe1f9e1602bdca45023e8d3db9db63237d + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549974e0c1a1b524048c2b37c669f275837a99381fa77f882cfbc2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663070ecf7cc85144673b207ee9a47874207daa4bf8a066372efbb +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=1e9a2da1ec0430295c3b8b7e1888bcb09293f61e62dfbdb29707348a95bdce292304418a554352333e6b377871f2d1e8d97a14c5bf5c035f4991b48c2c8ad26971d51de56abfc8ef0295 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9307b428397906f7e529cf6dd1bdf53f782a88f89a250c18dc83d57c9992dd +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8b1a7574e6cee466e01ba7f20e6cf372188b6294b43823ebc4c4c8a753b6e0 + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ceaaefa2a1d4a51bc7f72a564d71bc35 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=830ff5384b15750877d9469ab3b96e768a5e2fb618f00ca1e32da37d165221 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=832c1dca2a6b7c02b170c8d8cdec75e14983c8eae7ce6a07cc3392853455a9 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f70fa944b4bcd3d0d716f20a1eb95435666a15bb48ee700b648d33cef9f93019e0f8047ef1c51f2a5ff1cd3bcd30b6721663f533a5f40592962147438962718 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662ee035a51c82be8d63659f7a3dcb7efb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76707435fd3a637b4f9628bed8250d212f363d49580ee23c3edb82bc538cd2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afb8fe565768ec14254b79c64316cdd3895062d4533d37634fa8f3f273cb3 + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e8e12229cd4637c3412fe01f0b06cbbed1697731baf0add84a48598d80045cf16f2a56cf605314390dbffd940401319897aa7f01a4e35a1fe1e509be03f8d287 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660244d36287cc5719d495d63952e4bb9b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=781eb466f56d8404382803362e53dbfeab396f39e8614f70fd644325ce1803 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=86bfba9287f9d6663701546e14ccbad7b7e24be798aaf3f43a36a855d7ca62 + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541af3a1c3bc570ea6628903b6958854f3ccf77420136473d50d9ec58570d6ad5c4e176ab1a556abfa6141ec06d5ebe92ae95582f12402263635e5ddc2ab70d6d2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846620e5ec2a4f6ef544a3d54fa9185006e1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce130309e71e17105be8aa8b21f6f46258b99dae8d8818db759ea80677f64d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f2a1afcbfd92475f02b92eed96533323b3771c0c9833bbd87dd84373a89bc + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661df866ef53fc2daf09cd18e25f560f54e710d97f93f341248ad1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=830ff5384b15750877d9469ab3b96e768a5e2fb618f00ca1e32da37d165221 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=832c1dca2a6b7c02b170c8d8cdec75e14983c8eae7ce6a07cc3392853455a9 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f70fa944b4bcd3d0d716f20a1eb95435666a15bb48ee700b648d33cef9f93019e0f8047ef1c51f2a5ff1cd3bcd30b673d3b9677d899fc7f3d4b1258c0ff0ec33195ae6869722122a130 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466511d7d7f1904de2a67a43753ae73743bfca8e1aac9dfacb410ed +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76707435fd3a637b4f9628bed8250d212f363d49580ee23c3edb82bc538cd2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afb8fe565768ec14254b79c64316cdd3895062d4533d37634fa8f3f273cb3 + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e8e12229cd4637c3412fe01f0b06cbbed1697731baf0add84a48598d80045cf16f2a56cf605314390dbffd9404013198a9436856dc49b27a0698cb3ff57e3a14cbb3a80397fc12b67135 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846694b4c5866a584c0a70d8bee74ef35f21d601f7d4b9699b0a2c67 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=781eb466f56d8404382803362e53dbfeab396f39e8614f70fd644325ce1803 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=86bfba9287f9d6663701546e14ccbad7b7e24be798aaf3f43a36a855d7ca62 + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541af3a1c3bc570ea6628903b6958854f3ccf77420136473d50d9ec58570d6ad5c4e176ab1a556abfa6141ec06d5ebe92ae3533b3481ea038673f4428b39a64a07fc333516e98346439cd0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846603fa37b0787d046e5b39334226f42b1c63b64cb45dd4a9b095eb +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce130309e71e17105be8aa8b21f6f46258b99dae8d8818db759ea80677f64d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f2a1afcbfd92475f02b92eed96533323b3771c0c9833bbd87dd84373a89bc + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666660569f7c7fcd07d8e9d1a7c3634f60 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=830ff5384b15750877d9469ab3b96e768a5e2fb618f00ca1e32da37d165221 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=832c1dca2a6b7c02b170c8d8cdec75e14983c8eae7ce6a07cc3392853455a9 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f70fa944b4bcd3d0d716f20a1eb95435666a15bb48ee700b648d33cef9f930187a4370f2d9e5767873b7171e38897f591b606a1131011cee4173a3db7e22891 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f48a955b0b5cd099e7df95661e2862ad +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76707435fd3a637b4f9628bed8250d212f363d49580ee23c3edb82bc538cd2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afb8fe565768ec14254b79c64316cdd3895062d4533d37634fa8f3f273cb3 + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e8e12229cd4637c3412fe01f0b06cbbed1697731baf0add84a48598d80045cf11aaf3ee7de388d106596fdd48f72dd649b6b876b67bb13aeba09c64daf11ecd1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466060c96c5c428dca80c960fe9dd5a6ca8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=781eb466f56d8404382803362e53dbfeab396f39e8614f70fd644325ce1803 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=86bfba9287f9d6663701546e14ccbad7b7e24be798aaf3f43a36a855d7ca62 + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541af3a1c3bc570ea6628903b6958854f3ccf77420136473d50d9ec58570d6ad5cc18eb20f16747975cab6ac45d73488d66cc7b0294a6220498d30ba8bcf4f3952 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846644c3cae20a10acfac961f89a75b787df +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce130309e71e17105be8aa8b21f6f46258b99dae8d8818db759ea80677f64d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f2a1afcbfd92475f02b92eed96533323b3771c0c9833bbd87dd84373a89bc + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661df866ef53fc2daf09cdb07952c281cdcc4480337d476e359f64 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=830ff5384b15750877d9469ab3b96e768a5e2fb618f00ca1e32da37d165221 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=832c1dca2a6b7c02b170c8d8cdec75e14983c8eae7ce6a07cc3392853455a9 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f70fa944b4bcd3d0d716f20a1eb95435666a15bb48ee700b648d33cef9f930187a4370f2d9e5767873b7171e38897f53d3b9677d899fc7f3d4b2a7f9618049af0a0133f690fec587926 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466511d7d7f1904de2a67a437e109b3089a6a3efa6d5fe753113a09 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=76707435fd3a637b4f9628bed8250d212f363d49580ee23c3edb82bc538cd2 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5afb8fe565768ec14254b79c64316cdd3895062d4533d37634fa8f3f273cb3 + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e8e12229cd4637c3412fe01f0b06cbbed1697731baf0add84a48598d80045cf11aaf3ee7de388d106596fdd48f72dd64a9436856dc49b27a0698e39b1a331575f7dbc783c4b27db56d56 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846694b4c5866a584c0a70d80f9608c9ab477dd6be32ca78b3452e7a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=781eb466f56d8404382803362e53dbfeab396f39e8614f70fd644325ce1803 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=86bfba9287f9d6663701546e14ccbad7b7e24be798aaf3f43a36a855d7ca62 + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541af3a1c3bc570ea6628903b6958854f3ccf77420136473d50d9ec58570d6ad5cc18eb20f16747975cab6ac45d73488d6e3533b3481ea038673f4bae24ae04bf0f379985ae3359e56cf1d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846603fa37b0787d046e5b39156540f78e37ab584d177787c7570713 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ce130309e71e17105be8aa8b21f6f46258b99dae8d8818db759ea80677f64d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4f2a1afcbfd92475f02b92eed96533323b3771c0c9833bbd87dd84373a89bc + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a8121f6d88933f372d3d8558ba96c6a0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660b117a47d5ea6ba03a4e8a00f4bc0e88 +msg_2_payload= +msg_2_ciphertext=2a607b984bb2614e9c6b84c0a735f9cd1e4bf3ff01edf33d6626f16ac1f12f0c5230239edb11e337d70427365bb94949ce7fda351e4f8ca43da1e91c0559d921 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=af719ddf29a7df759e00d10bf397d6e72d961dfa146e38a48e8856747db349 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=01cb205a382fe3800d1194755b30433dc1250c4e9ab65581919777e1e31862 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e5f2f445afe0d790bd2631a553574915 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846641ccb8f7db404e7089382d696e3f2043 +msg_2_payload= +msg_2_ciphertext=10fd75cdb4d7a71ef3d8713d7d3ee0fe77eefaac88a1cc0e8fb1c8598830a26ca429ae726b1c48e9af560b971005eccd788717c413004ef0a0fc54b26fc39d72 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6c00201f24d7406b7a41e346011509fc9726bf3cd3fcb0099f893241f292a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4385be501f1af8ec43aeb67163036606dba4b666f59e77f89ce03b86efaf3a + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543336582f35b4811afc0009c5bfe23fb6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f0b2cda351a7491a1a8d233f694a900f +msg_2_payload= +msg_2_ciphertext=d9ecc3d1ca57c998fe713d129c081b9b8ad9ce9a519179902a57600b30ce6f5cd976176cc09af329cc934132ef8e22b2ad160e39304ec60451a20c5d535db720 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd90a09b18aca3fb4322a97ba23a61973ef7a0617af12ac48a9a1ce3a59cdc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b139c0e387155e21af5751ced5df67d118e4ec857c5aad862bc90a024853bc + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545a532081892316ccc914c1f41b95fd32 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846620d7abc3c895614c290126a72d27e586 +msg_2_payload= +msg_2_ciphertext=d3a8c16bc7ec7a53b13ed69e7307bfedb166350efaafad356bbe13865f8305b4271fa9f8941fbb5227e2e99ca7272ad4cf688f2a831138f199cfd07f2048b360 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8b8306bca22f2ba97f257b5658a95c6c17aeb73208ac47adb53e6f34f32dda +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3ccc1f6d694e1f807baa7077c3917823fd3d5d0c1acb9a819dc2ecea0740d3 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625467ece9526c5e98a95ef06540641ce080 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846669b9f0e8b083bd61a6ee3c2d1376b7ce +msg_2_payload= +msg_2_ciphertext=cb86a2b771eb68b697b00603224426b59b2e4cc522c385955fe80b89936fdc879d6ceedd6144d1f246e83474db6628e531eef9b73bece378cef0d0783c520c44 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9961ea7152c68324f433f74f14cf453872f922c078365f6eb72d1eaab869ed +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57c5a35b57323a4841a2535029c297d298028e10e798e0fbcca41110ff6bc1 + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6cb6fe7e80444bb3154cc8c6ee7d1303de77495fc986b7ede43 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846671a438132a5b2eb4b6a07e26cde62f24cc303c50baebbc111c88 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2a607b984bb2614e9c6b84c0a735f9cd1e4bf3ff01edf33d6626f16ac1f12f0cbae76bfc135b5828a7ff27f023ea59cc8dc0802c5d9d369d77f4bcf1bdd8a6c3205c28db784528897fcc +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=af719ddf29a7df759e00d10bf397d6e72d961dfa146e38a48e8856747db349 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=01cb205a382fe3800d1194755b30433dc1250c4e9ab65581919777e1e31862 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b45ff089253cdcc224ba73eab621cc196ddf50935e457ea5640 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667d787668fb251e9de3b703c7a10f7f6541db12cfde30137eb731 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=10fd75cdb4d7a71ef3d8713d7d3ee0fe77eefaac88a1cc0e8fb1c8598830a26c3a7a94677b6f6971a918b1f6142f0f8add5ea9a3086edd1694264640113dafd9941831d9f8e59458af6c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6c00201f24d7406b7a41e346011509fc9726bf3cd3fcb0099f893241f292a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4385be501f1af8ec43aeb67163036606dba4b666f59e77f89ce03b86efaf3a + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f7aa65da5c5393de3c5535e15dbfb46a665260e9f00887efb923 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466578656f83336512ba12d91d1410dee12011adad4e28674496199 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=d9ecc3d1ca57c998fe713d129c081b9b8ad9ce9a519179902a57600b30ce6f5c761b50e9f3ba0c4d57466b8b7f36c21246578936ef0f0cde78ec9962c6dc167becb1bb4943c865e84f44 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd90a09b18aca3fb4322a97ba23a61973ef7a0617af12ac48a9a1ce3a59cdc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b139c0e387155e21af5751ced5df67d118e4ec857c5aad862bc90a024853bc + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540e6f56acb931ce6a0d25e1f25351be198ed759a1ef122e6a47c5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc88a17b8b5854bac07fd6b2a163ca81ce377f77ed9a6565f2ff +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=d3a8c16bc7ec7a53b13ed69e7307bfedb166350efaafad356bbe13865f8305b479ef186dc0bf7da9b3969fc460549a4f75ef7aedc759cb34d7baf24c96274d5de3ea057059bf346967bb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8b8306bca22f2ba97f257b5658a95c6c17aeb73208ac47adb53e6f34f32dda +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3ccc1f6d694e1f807baa7077c3917823fd3d5d0c1acb9a819dc2ecea0740d3 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ef3e6a97158d33a0e062f662ee40189264748f8f4669b195157a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e69d80c877ed191a57840a873d4d140ed15adb13fc5e0faceae5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=cb86a2b771eb68b697b00603224426b59b2e4cc522c385955fe80b89936fdc8768b3221f7eb3474b3a397b412566a083eae667065d5d8520f96dc500ef05901b2c97eb3e257b5b641688 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9961ea7152c68324f433f74f14cf453872f922c078365f6eb72d1eaab869ed +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57c5a35b57323a4841a2535029c297d298028e10e798e0fbcca41110ff6bc1 + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254956f94f7a6fcc381776893a9419a1391 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662dcab0911950a5414c1739ef201b0d59 +msg_2_payload= +msg_2_ciphertext=2a607b984bb2614e9c6b84c0a735f9cd1e4bf3ff01edf33d6626f16ac1f12f0ce46707d4054136e38d139c40429a1c7bdfe2618fcd66e1d1c993a5d724149ad3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=af719ddf29a7df759e00d10bf397d6e72d961dfa146e38a48e8856747db349 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=01cb205a382fe3800d1194755b30433dc1250c4e9ab65581919777e1e31862 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625480f041b1faae93dc9ad4e24164074a72 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466049ae30e300696665182cd0c2c5a3333 +msg_2_payload= +msg_2_ciphertext=10fd75cdb4d7a71ef3d8713d7d3ee0fe77eefaac88a1cc0e8fb1c8598830a26c27529778073a3c1eca1366f61e1e6df01f4c362cabd86d507f717372d3b42cde +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6c00201f24d7406b7a41e346011509fc9726bf3cd3fcb0099f893241f292a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4385be501f1af8ec43aeb67163036606dba4b666f59e77f89ce03b86efaf3a + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625459b3fc3e146bee1bedd48d2e529619c9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d8091dc1177e44919beeef55f461c8f5 +msg_2_payload= +msg_2_ciphertext=d9ecc3d1ca57c998fe713d129c081b9b8ad9ce9a519179902a57600b30ce6f5c82a04833784ccfb5e9722ca5241a6755c3cbc5f3606b84da1baa6576e7b927d8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd90a09b18aca3fb4322a97ba23a61973ef7a0617af12ac48a9a1ce3a59cdc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b139c0e387155e21af5751ced5df67d118e4ec857c5aad862bc90a024853bc + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254de5fed603c0f5e7048cde4754accb939 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664a79bd841524585be070029e87cf5b17 +msg_2_payload= +msg_2_ciphertext=d3a8c16bc7ec7a53b13ed69e7307bfedb166350efaafad356bbe13865f8305b4c5551963da60c1367a4ddb92d1aeebab7f9e1068c5b07e44cd6de3b644761c55 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8b8306bca22f2ba97f257b5658a95c6c17aeb73208ac47adb53e6f34f32dda +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3ccc1f6d694e1f807baa7077c3917823fd3d5d0c1acb9a819dc2ecea0740d3 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a20106c4f0d2e1d15b488b9120d587a7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664cb1d6364acf843b72742c6e40fb7816 +msg_2_payload= +msg_2_ciphertext=cb86a2b771eb68b697b00603224426b59b2e4cc522c385955fe80b89936fdc876f2d10e9970e2e2a05abf249856727901c01817fcd79e7bb15ca824f74e20dbb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9961ea7152c68324f433f74f14cf453872f922c078365f6eb72d1eaab869ed +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57c5a35b57323a4841a2535029c297d298028e10e798e0fbcca41110ff6bc1 + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f6cb6fe7e80444bb315499a7f5f08590af0d50a5359f99e54dbe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846671a438132a5b2eb4b6a09e2096243969b42b4b9a198dc894d2e9 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2a607b984bb2614e9c6b84c0a735f9cd1e4bf3ff01edf33d6626f16ac1f12f0c0912c9cd375503ce9e805b172ad0d4698dc0802c5d9d369d77f4ade77f73640bd9d60f3899f36dfde35b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=af719ddf29a7df759e00d10bf397d6e72d961dfa146e38a48e8856747db349 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=01cb205a382fe3800d1194755b30433dc1250c4e9ab65581919777e1e31862 + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b45ff089253cdcc224b4eb91d5554d75cc6efe1975d9068377a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667d787668fb251e9de3b7940a90cd22958f5cbf27ca154b6b22de +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=10fd75cdb4d7a71ef3d8713d7d3ee0fe77eefaac88a1cc0e8fb1c8598830a26ceb2af92575fa2c196715cdff6e5a2bd2dd5ea9a3086edd169426bb9c6f9f3ef69ab1bca891788d793838 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6c00201f24d7406b7a41e346011509fc9726bf3cd3fcb0099f893241f292a5 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=4385be501f1af8ec43aeb67163036606dba4b666f59e77f89ce03b86efaf3a + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f7aa65da5c5393de3c5548df4e50beec4d5d686ea0a58b5d7c07 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466578656f83336512ba12ddb9299155eb66d8b8c563c46b2650045 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=d9ecc3d1ca57c998fe713d129c081b9b8ad9ce9a519179902a57600b30ce6f5c7c893705678fdd420468b74e00732ced46578936ef0f0cde78ec005dc5d6cedeee43ee05dcddc151e174 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd90a09b18aca3fb4322a97ba23a61973ef7a0617af12ac48a9a1ce3a59cdc +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b139c0e387155e21af5751ced5df67d118e4ec857c5aad862bc90a024853bc + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540e6f56acb931ce6a0d25a7d58f03a624f2edffe6889a3cc1bdb4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bc88a17b8b5854bac07f57eb97d0e6556bd36bf0765632a4a0d9 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=d3a8c16bc7ec7a53b13ed69e7307bfedb166350efaafad356bbe13865f8305b495169d8ddfd2ce2b08da7fb2185ad2f975ef7aedc759cb34d7ba5b6a6521406803adf71d8e3f467e6b5e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=8b8306bca22f2ba97f257b5658a95c6c17aeb73208ac47adb53e6f34f32dda +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3ccc1f6d694e1f807baa7077c3917823fd3d5d0c1acb9a819dc2ecea0740d3 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ef3e6a97158d33a0e062dfd67d4d95e6b70c838462a3c8f93c11 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e69d80c877ed191a5784108e0821d062d135c79ecd1e1d32e495 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=cb86a2b771eb68b697b00603224426b59b2e4cc522c385955fe80b89936fdc879e3d3e2544d69c1bfcb5c318fcadaf1beae667065d5d8520f96da952f2d9dd6784e56b3af33f9e2f6a7d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9961ea7152c68324f433f74f14cf453872f922c078365f6eb72d1eaab869ed +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=57c5a35b57323a4841a2535029c297d298028e10e798e0fbcca41110ff6bc1 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471316e70ec2670fe80a4529101864a5dac3d5f9c0924e8d38cecd60c54adbaa284b6111d7779c4ee7bb9c56da492e5a80972d99ccbf7d9068e6e90a7a73a01e9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666953a0bb0be9e3cb75769d93c5a16090 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dc52cf04c64e4b750c00444789e41cb1abe496381a2d1b42303b231e809437 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4e39fa2317aba599efd3f7a7ca1de12dfae13bc630cc8768ce6326894fb250 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548a773d92dab8d730d4809faed6fbf25151dc4609a2020980934c02fa2026e50395c19e290fc2b0ebd1926e25516eaa74382fef41e27d86725aac235f5ec54486 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667c6f4245d9e5b32e9e357b2b8858590d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=186910b9f7f96154beaaa85cd7bc247243468524c12329a05a42ca5a36c68f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cd2f07315236b6e428120a37bbfaab7b1c58f4d55a2242e02c6e7bb943500b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540d9201affcf03e61b649d92ff393eb2ee186823f5369731162b2f772cfc6371bcbe8d7e19394282f1efe8a67e2b8322dbcac776930e9ed0a112705ef2f6f2fb6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846645235dc77860e6902834d55b53616e13 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c64fdb57aa336721d15fb7ab26fe477cda48a1bf9e0ad3bc4cd554b0740b7e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7601a7f5ac11f9241580f13b13d47a05b9e0ac4a31aa9229b455d6850f6f4 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b62f8e1b309574de35d98d9a4088e6919c1849b2c5254dcbca5494537cb4a72988a30055e89f105e4a2ec94ffe1e01b210d70746671e7bffca493129849aeff4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466aa41d4650249b9c0c26cbc1ce87e8c1f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4c177d26066f6951689eeb7dba6199b0a71514482d9fd58cab9c9da5ebe95 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=15e2992826a7c63bdc9c36c422f0625aa3cddb283aaf9aea44444d8ffdbe82 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471316e70ec2670fe80a4529101864a5dac3d5f9c0924e8d38cecd60c54adbaa284b6111d7779c4ee7bb9c56da492e5a86e5ed547305fd8e63d0c6f2932f3a5c642bda3b85699cfd4af02 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b0981ce42d3aee24e400cc2d7c0851db983a76950d68ac02018e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dc52cf04c64e4b750c00444789e41cb1abe496381a2d1b42303b231e809437 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4e39fa2317aba599efd3f7a7ca1de12dfae13bc630cc8768ce6326894fb250 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548a773d92dab8d730d4809faed6fbf25151dc4609a2020980934c02fa2026e50395c19e290fc2b0ebd1926e25516eaa74a8c2db362d37b8bd047718944128a324cc8464b8770aa0edb54d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fa4432021f183c112445ce9dd4839730062f80545088527f6ab7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=186910b9f7f96154beaaa85cd7bc247243468524c12329a05a42ca5a36c68f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cd2f07315236b6e428120a37bbfaab7b1c58f4d55a2242e02c6e7bb943500b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540d9201affcf03e61b649d92ff393eb2ee186823f5369731162b2f772cfc6371bcbe8d7e19394282f1efe8a67e2b8322d2307641fa5171d2e6a90b7327908bd3a4c0ba2647c9fbf326342 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6777d6ce0d20a6334912c2cce256a5baafbb4981cb3b57e2b7f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c64fdb57aa336721d15fb7ab26fe477cda48a1bf9e0ad3bc4cd554b0740b7e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7601a7f5ac11f9241580f13b13d47a05b9e0ac4a31aa9229b455d6850f6f4 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b62f8e1b309574de35d98d9a4088e6919c1849b2c5254dcbca5494537cb4a72988a30055e89f105e4a2ec94ffe1e01b2e07148a37250771da813ab2d25f8ebfd885dbf1a2d381a28b36e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846655590e80a4cbf7b11a80ddd081ca9aca27a45d1ad37939362f98 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4c177d26066f6951689eeb7dba6199b0a71514482d9fd58cab9c9da5ebe95 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=15e2992826a7c63bdc9c36c422f0625aa3cddb283aaf9aea44444d8ffdbe82 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471316e70ec2670fe80a4529101864a5dac3d5f9c0924e8d38cecd60c54adbaa2f602a28ed62afc1421fb6217fa8bb34ec2ffe02e3cde39a920ebf369ebc4d7e2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662b2ab0ecf235887681b76ad519b29032 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dc52cf04c64e4b750c00444789e41cb1abe496381a2d1b42303b231e809437 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4e39fa2317aba599efd3f7a7ca1de12dfae13bc630cc8768ce6326894fb250 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548a773d92dab8d730d4809faed6fbf25151dc4609a2020980934c02fa2026e5035a6b8c83d8d35b4be37728726934df7fa54ca976c7ac99763b5b503dedabf110 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667c2bd068de83287251c4332dfaf109e3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=186910b9f7f96154beaaa85cd7bc247243468524c12329a05a42ca5a36c68f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cd2f07315236b6e428120a37bbfaab7b1c58f4d55a2242e02c6e7bb943500b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540d9201affcf03e61b649d92ff393eb2ee186823f5369731162b2f772cfc6371b56d4c205efdaadafe7ad43991634897df8a65cce5462ff5edf7a3cb303d23cb5 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c1bd3e2fdbb59170ea903582e5173315 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c64fdb57aa336721d15fb7ab26fe477cda48a1bf9e0ad3bc4cd554b0740b7e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7601a7f5ac11f9241580f13b13d47a05b9e0ac4a31aa9229b455d6850f6f4 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b62f8e1b309574de35d98d9a4088e6919c1849b2c5254dcbca5494537cb4a7295084dc6a278b90d5443be18249717177d5e8e7d7aa1d5047cac7e122ceb801eb +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667276e5a1b63d8f369009fcbf44acc6b9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4c177d26066f6951689eeb7dba6199b0a71514482d9fd58cab9c9da5ebe95 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=15e2992826a7c63bdc9c36c422f0625aa3cddb283aaf9aea44444d8ffdbe82 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625471316e70ec2670fe80a4529101864a5dac3d5f9c0924e8d38cecd60c54adbaa2f602a28ed62afc1421fb6217fa8bb34e6e5ed547305fd8e63d0c7272edad8555d9482a258f9fcd94b9b2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b0981ce42d3aee24e4004d6ea9acd8a847242a19f3f0f4cb0976 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=dc52cf04c64e4b750c00444789e41cb1abe496381a2d1b42303b231e809437 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4e39fa2317aba599efd3f7a7ca1de12dfae13bc630cc8768ce6326894fb250 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548a773d92dab8d730d4809faed6fbf25151dc4609a2020980934c02fa2026e5035a6b8c83d8d35b4be37728726934df7fa8c2db362d37b8bd047781dee28aded1f414d2c10d890fa2eba1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fa4432021f183c112445d6ff055cdbdc1b47a925e1550a0242a2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=186910b9f7f96154beaaa85cd7bc247243468524c12329a05a42ca5a36c68f +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=cd2f07315236b6e428120a37bbfaab7b1c58f4d55a2242e02c6e7bb943500b + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540d9201affcf03e61b649d92ff393eb2ee186823f5369731162b2f772cfc6371b56d4c205efdaadafe7ad43991634897d2307641fa5171d2e6a90d2f10229135bee69c5e8987beeaff24e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6777d6ce0d20a633491e32380e0bba416095b23e6c06497fd0c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c64fdb57aa336721d15fb7ab26fe477cda48a1bf9e0ad3bc4cd554b0740b7e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7601a7f5ac11f9241580f13b13d47a05b9e0ac4a31aa9229b455d6850f6f4 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b62f8e1b309574de35d98d9a4088e6919c1849b2c5254dcbca5494537cb4a7295084dc6a278b90d5443be18249717177e07148a37250771da813c0db249d31475e830bbcc50ce9aeab43 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846655590e80a4cbf7b11a803755ea3f2276bcb10438d218a79e05cf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f4c177d26066f6951689eeb7dba6199b0a71514482d9fd58cab9c9da5ebe95 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=15e2992826a7c63bdc9c36c422f0625aa3cddb283aaf9aea44444d8ffdbe82 + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b0b018e349141e1b16c68fe9a6cb1183c260c44bb83c93a140953ad45612b8c64bb3b17125ca3fb8cf0cd955affd684b70d7a73e49f11219837f16d3f7544832 +msg_2_payload= +msg_2_ciphertext=b4c5f23f127237b5a80ac12f3a3548fe46c39172f6b180eb1e023e6e19e283eeb2c9403c731010215a57c3149b0f7aaec1f10503228b36cd1662e940ecc38fd5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=adcafe99678efda6f3d8c84a8fd41a63bb2cfc85aa6eb8ff3dbf724496b03e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=51d5c55fb055dc171c4bf7618270e30b393601f44f3a0abd7c276b63093c1a + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e89ad728d1b3555e8affba774c455ecf +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466def8302a4ce14b6d8679764f5605d198853b8968688d7432e591c0371dbd9c271e7509b3366c251d193c2b6173162f24bfb214c9912e36dbc2bebcd0c5a41310 +msg_2_payload= +msg_2_ciphertext=7ae518aa6a3882fac6b6d6fcd88954cccf404ea1aa2a075d533916de39720ebbd5a2fc7c5df275e6d9ac02a752f651f67f737345e8c1310db32861d8fb0233f9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd0638db68611323934a1dc1c26175ddc9abfbf887629ce59b4303156bcaa1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3d9c9f74481ef29d381234288ecb1d26afa997692fff8407cbf6da726a5725 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fa223f36e9139a40a9551700c5636675 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ce56429bffb894f3369b30a544d455d8f184f93f9c842bbe985dde8e576dd8eed8438aa1768e3aa2b4ad1bebf0a92b156771c02032ed9387687cca42cb786162 +msg_2_payload= +msg_2_ciphertext=4897d20141b9271678aeff91ee7005ca77d69a228f23d79eb6ac67cecef3224f6f88b8b1d486e5d50a397d526deb513cf18ed7a50ff9722cef519cfdd08f2ed8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=4c7e74911721ae8c0678065a0f6ad8fb1297a21f6754b38e266eee19d0ad2a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=475800d09b8bf0421df0e7679d3cd21b814fd6dff0fb9c46dbc5376c6122e4 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a0282a4879cb0deb654bdede7e9be90b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661e036fa970ffb21503a0108b83c0bd72003bb6d4a97179484514ff7ef45ec9eb9bdbfd37a4b660583fab7b211f1b3503b00b5e97afc5b32665b370e6478b524d +msg_2_payload= +msg_2_ciphertext=94ed14201939c7bb4572b20adf4082cd6bb82f70f3c8de3316bc33f5eae48cd9ddd25dc1383725178c8598f5fba81ebb96531a3239965542dbb5b6788e6c69ff +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86774279eb88fc06ae6805d0b449a143cdfe04a11fc7a429277b968cabe3bf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1f80227766841582344bc541607b227d94329c13eacc906aa8d505877ba86 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254813e50d4de1a8d4e0d61efe2041f7ca6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f05a4cb6e4cb79e094bd585a0b9fbc734db005568fc515c58c9fde6291e3e29220fbe03545fe15b4e8e1acca1559b4b2de52d9ae55517db0f969b67cfd1a046a +msg_2_payload= +msg_2_ciphertext=8651088810f5c175e542fa61507d8cfac7670c9c1f1e3eb7c8fcfa1e632b0d466be2a1a293e4da8f69787704224eafe4849020203ee23d283e335821b48f1adf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ff43d872c9028bdb9c54fa2c87bf427cd7fdf53b281d89649f183629b8f2e9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=50ca5d06223b9346bc628ee151bf174732e4afc56fe3fca4baff4173abe983 + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b0b018e349141e1b16c68fe9a6cb1183c260c44bb83c93a140953ad45612b8c6c9a7ce6964ece59add85b2606ced1d6d19d85b03583048e0c2c9a492b15d90479c7b9af68fb1a47696d5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b4c5f23f127237b5a80ac12f3a3548fe46c39172f6b180eb1e023e6e19e283eec8b71c2ce9c0e29ca1766034c2c8feb14cb940f335a08c03246384d70b9a8ae83fd96cea468098f1f8d9 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=adcafe99678efda6f3d8c84a8fd41a63bb2cfc85aa6eb8ff3dbf724496b03e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=51d5c55fb055dc171c4bf7618270e30b393601f44f3a0abd7c276b63093c1a + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541fe2db7a97bbe9c0027b7090cb11725f0947318b6d1f1ad08ce7 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466def8302a4ce14b6d8679764f5605d198853b8968688d7432e591c0371dbd9c27e50840bb3f7e4c87ca8f5414ba3078aa5c032641bc1cdaccd5aa58bfd328b2972ff47f99ced9a6b7aef3 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7ae518aa6a3882fac6b6d6fcd88954cccf404ea1aa2a075d533916de39720ebb186eba1bc5bdad09bcab5739864ca692519efda7f74013ae0602622d1accdeb04f261e1eb1ada91b5a00 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd0638db68611323934a1dc1c26175ddc9abfbf887629ce59b4303156bcaa1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3d9c9f74481ef29d381234288ecb1d26afa997692fff8407cbf6da726a5725 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625483cfed638fb3c56f6e445c3225fd44968f7a179313516eb5c1a9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ce56429bffb894f3369b30a544d455d8f184f93f9c842bbe985dde8e576dd8eef9072a865ec6acd45a95e6d5699cf88ab1adaf886733195012b10e6cd5389e4046ec7b8620170cceaf17 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4897d20141b9271678aeff91ee7005ca77d69a228f23d79eb6ac67cecef3224f04191a5af016de4910629179a06d26cadb2c8b23157b86216ebf371933ed5d042b8b69d9b202f343b7c2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=4c7e74911721ae8c0678065a0f6ad8fb1297a21f6754b38e266eee19d0ad2a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=475800d09b8bf0421df0e7679d3cd21b814fd6dff0fb9c46dbc5376c6122e4 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540f55bdaaa880fc12facbe60813c0db272c15e442ff0938e3533a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661e036fa970ffb21503a0108b83c0bd72003bb6d4a97179484514ff7ef45ec9eb2c798e8efacdd62b6bf5244df69c8c3aa2494f38471537cc5d6b6504593989137c09964cbdfe9eb3d3e9 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=94ed14201939c7bb4572b20adf4082cd6bb82f70f3c8de3316bc33f5eae48cd99924bd9d5a06fe3a5583f3a383313d93e7a7158f06660cce13843fa445d1bf333858f033b9294adcacf0 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86774279eb88fc06ae6805d0b449a143cdfe04a11fc7a429277b968cabe3bf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1f80227766841582344bc541607b227d94329c13eacc906aa8d505877ba86 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541bb344a916e3fe400ded24cb3fa734c93f22004e92da97dbce1d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f05a4cb6e4cb79e094bd585a0b9fbc734db005568fc515c58c9fde6291e3e2928d5c8ea8af6ef701c52ab3e57ada1d472451c80484377ba18cd7418f721d9d21744f1ad65da0279a66fb +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8651088810f5c175e542fa61507d8cfac7670c9c1f1e3eb7c8fcfa1e632b0d4638dea852a90ce28331a393758df509cdfaeeeceaa062fd82e223c30f70e0e273f7d7dbf386acf966ddf8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ff43d872c9028bdb9c54fa2c87bf427cd7fdf53b281d89649f183629b8f2e9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=50ca5d06223b9346bc628ee151bf174732e4afc56fe3fca4baff4173abe983 + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b0b018e349141e1b16c68fe9a6cb1183c260c44bb83c93a140953ad45612b8c67f6ad77fe0172d65f35620f8d6f0b8db7eaf545a402e665786d189c5c7e2bef0 +msg_2_payload= +msg_2_ciphertext=b4c5f23f127237b5a80ac12f3a3548fe46c39172f6b180eb1e023e6e19e283eed57a951543a0ab0645958f932e50a2743423286e6494f7c453bed71b63a1bb91 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=adcafe99678efda6f3d8c84a8fd41a63bb2cfc85aa6eb8ff3dbf724496b03e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=51d5c55fb055dc171c4bf7618270e30b393601f44f3a0abd7c276b63093c1a + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254daabd705d9da7c80c426df55902fb9cc +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466def8302a4ce14b6d8679764f5605d198853b8968688d7432e591c0371dbd9c27c142d82a45eca7997eeec4e81381209cd1cc75dc52230a6ad5dc90432748d6df +msg_2_payload= +msg_2_ciphertext=7ae518aa6a3882fac6b6d6fcd88954cccf404ea1aa2a075d533916de39720ebb5a679823352dc4b0bbbb47c9dc418fbf6185f09c57410138d19557733bdfd046 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd0638db68611323934a1dc1c26175ddc9abfbf887629ce59b4303156bcaa1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3d9c9f74481ef29d381234288ecb1d26afa997692fff8407cbf6da726a5725 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546693cc146b829f659b3a3a6f36062417 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ce56429bffb894f3369b30a544d455d8f184f93f9c842bbe985dde8e576dd8eee6e90c6418f739bec226dd5fa5dcd4cc0f4524e463ccf85bcef7c086833474b4 +msg_2_payload= +msg_2_ciphertext=4897d20141b9271678aeff91ee7005ca77d69a228f23d79eb6ac67cecef3224fce9e99b2d8ffbd7aec4d8c8df6c5a172de9a9714a6af6b1234f1620b8645e579 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=4c7e74911721ae8c0678065a0f6ad8fb1297a21f6754b38e266eee19d0ad2a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=475800d09b8bf0421df0e7679d3cd21b814fd6dff0fb9c46dbc5376c6122e4 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254774c69f7d11f794ed54a4bf91f16fd2d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661e036fa970ffb21503a0108b83c0bd72003bb6d4a97179484514ff7ef45ec9eb96af227896014838fc1945263ff54bd5375932b16efea120c62ed8a315420f6c +msg_2_payload= +msg_2_ciphertext=94ed14201939c7bb4572b20adf4082cd6bb82f70f3c8de3316bc33f5eae48cd9e6d85d2c7f133960dc1f8e448a65d585cea1481e2d35d543ea5429a592eabe47 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86774279eb88fc06ae6805d0b449a143cdfe04a11fc7a429277b968cabe3bf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1f80227766841582344bc541607b227d94329c13eacc906aa8d505877ba86 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c21324e86ac7d65b7dc06cf3b651e32 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f05a4cb6e4cb79e094bd585a0b9fbc734db005568fc515c58c9fde6291e3e292a276b6138dab236a57f9a781388562c174bef9f634ada92d349e837ac7ccd978 +msg_2_payload= +msg_2_ciphertext=8651088810f5c175e542fa61507d8cfac7670c9c1f1e3eb7c8fcfa1e632b0d46bb08fbcd509f32a5dfabbf43a22dbc5e5002092ca11ba0dddc4faedad0330f85 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ff43d872c9028bdb9c54fa2c87bf427cd7fdf53b281d89649f183629b8f2e9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=50ca5d06223b9346bc628ee151bf174732e4afc56fe3fca4baff4173abe983 + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b0b018e349141e1b16c68fe9a6cb1183c260c44bb83c93a140953ad45612b8c682f5a2957440f5f83a39a24e5cb2627919d85b03583048e0c2c936d254bb86813590fe0b415b3271c451 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=b4c5f23f127237b5a80ac12f3a3548fe46c39172f6b180eb1e023e6e19e283eee243c226bfded175cebcfe8ec14f27024cb940f335a08c032463eeca3f18039cd75586b07daff31c4dff +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=adcafe99678efda6f3d8c84a8fd41a63bb2cfc85aa6eb8ff3dbf724496b03e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=51d5c55fb055dc171c4bf7618270e30b393601f44f3a0abd7c276b63093c1a + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541fe2db7a97bbe9c0027b1f62071910cfd2266573bb14a7de4342 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466def8302a4ce14b6d8679764f5605d198853b8968688d7432e591c0371dbd9c27c0e397d4a328006c00af1dc428f95bc55c032641bc1cdaccd5aae41c3d70b1d39ac256cf6c07a7430831 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7ae518aa6a3882fac6b6d6fcd88954cccf404ea1aa2a075d533916de39720ebb1eaeb854d104e73a1406c7ff4ad6beed519efda7f74013ae060269ba43ed1a294c9c44cff50595ad1324 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=fd0638db68611323934a1dc1c26175ddc9abfbf887629ce59b4303156bcaa1 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=3d9c9f74481ef29d381234288ecb1d26afa997692fff8407cbf6da726a5725 + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625483cfed638fb3c56f6e443f8097c23fee7a3b76149d56e41918a5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ce56429bffb894f3369b30a544d455d8f184f93f9c842bbe985dde8e576dd8ee8ca69106df75e49f29eaae67fa71a409b1adaf886733195012b157ffd83ea7ae659b0902222ed9440be7 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=4897d20141b9271678aeff91ee7005ca77d69a228f23d79eb6ac67cecef3224fc3f318361519b4d6ffa8722b937eda33db2c8b23157b86216ebf80415aa89e935fb92101ea57f6ec5669 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=4c7e74911721ae8c0678065a0f6ad8fb1297a21f6754b38e266eee19d0ad2a +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=475800d09b8bf0421df0e7679d3cd21b814fd6dff0fb9c46dbc5376c6122e4 + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540f55bdaaa880fc12facb47d5793c5c9c2c879cfb8cb55945655f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661e036fa970ffb21503a0108b83c0bd72003bb6d4a97179484514ff7ef45ec9eb07357830807daf32b9a32297a1a9878da2494f38471537cc5d6bd4192f5f3078085f0533aa0e75686fba +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=94ed14201939c7bb4572b20adf4082cd6bb82f70f3c8de3316bc33f5eae48cd9b530622c64695f7e4ce8f79b3ef119fbe7a7158f06660cce138493700e351a7a22ae1bb11889ae401722 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=86774279eb88fc06ae6805d0b449a143cdfe04a11fc7a429277b968cabe3bf +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b1f80227766841582344bc541607b227d94329c13eacc906aa8d505877ba86 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541bb344a916e3fe400dedd2a7371c38b355300008ffe1f92c5321 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f05a4cb6e4cb79e094bd585a0b9fbc734db005568fc515c58c9fde6291e3e2920a77f6c331f2b9e51cb445ebaa762dd12451c80484377ba18cd74ca6e49295ef6417ad4b265ac043c90e +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8651088810f5c175e542fa61507d8cfac7670c9c1f1e3eb7c8fcfa1e632b0d46f22ae59817305950a50b328539a252ccfaeeeceaa062fd82e2237a114a9d10610aa66213ef7dbb4f0ebc +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=ff43d872c9028bdb9c54fa2c87bf427cd7fdf53b281d89649f183629b8f2e9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=50ca5d06223b9346bc628ee151bf174732e4afc56fe3fca4baff4173abe983 + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660d08c6ebb96e008cec2c0c4667d8488bfa63fb9542b9543bf2f44452ddfca2d7b47846f7c23a61ba89e3005c17a3da874f0113c4bcaef064e33c7388076221f1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4ce1063a2c24a067d32c33bc634f9164349ff4d51e2f736aa8ddfe7d85dbde +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e8ec223c4616b42db4b40ac577af6937537a779ffc4517314c4c90e6c6bec + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b63d4823ec3c33b747175212d3fa59c7320419f05114fa56bc49c588ce3efae0f7a0096cf97cac10155a9af45a6fa4a568a065542312cfca94b12f8721a77ee9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663960d18951259c9250ca1804369d267c7a61ba56041491bbe42dac780957c6c53b4073645443610174b25add1f889f59292b4d5756ee87a43c557907cefe7ee3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9c8ed9bfe0b9016461bf4ab1d3f56b261cbd5f0c9a165184fcfbe28af3968 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81bfdb36c9b8d755d0ebe25f87edd262896108dfa2b073c0814093f7d2ebd8 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e48b3f70e18e77885fa9aacad3100d7678a827d00fb563dcd477899b1ee1d89e23ecb8f2999013a2043036cea9c6d610ab3d9d45672d615f56e14a907a6626ef +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba047e6e3ee18a0dcb8a530689f90df6155ccc5cb33a0b378c4885b36c315b433e6294711d4def132673d121030ade3f074c8ce7ac45822d01166f7efabff8a0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f98369e9445c5882aa703756b77e75713ba3004075fa24c018653a1b4d103b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d842e68c723ec899be6e97299547bfae1c1c2666c328a4cc939f33d2be6eb3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3be70df2112be564394441fab73a3d1ea8cffbf282cb7e2fba6d4bf93eb3d0e546334907b6a75b27e91ddf1f4bb8265c5dbe3134d556ccda881f6735a439202 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6538498df27580b5a8ce84806413a0bb3fef6548807b7675d415b295a36312997861b158cfe7287bc38d8d22edc615342716e16b46f10a0099c7c8d5984039a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bd6813d28352fec1b43d31a7c1f39f37c4800d82a6281fcfc81eae0b97d3b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b1ea910350e67ec24ed0f3c557ff265133851bdafd4c7aea32ba5a7624f13 + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660d08c6ebb96e008cec2c0c4667d8488bfa63fb9542b9543bf2f44452ddfca2d7e4427f5970f26a10fd1072dbd7a0836bbd3886d3f59490443484ed8534285770555656ca00988f52612d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4ce1063a2c24a067d32c33bc634f9164349ff4d51e2f736aa8ddfe7d85dbde +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e8ec223c4616b42db4b40ac577af6937537a779ffc4517314c4c90e6c6bec + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b63d4823ec3c33b747175212d3fa59c7320419f05114fa56bc49c588ce3efae0f7a0096cf97cac10155a9af45a6fa4a522e8eb3d61d2bb8d5009943c3bf446f032c0b794ddc1c18d137e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663960d18951259c9250ca1804369d267c7a61ba56041491bbe42dac780957c6c521f538e34bfd357ad7040f461cb64b9987381dbd1f2b9a676c279d5af171ea9f30c5941cb2be937e43c9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9c8ed9bfe0b9016461bf4ab1d3f56b261cbd5f0c9a165184fcfbe28af3968 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81bfdb36c9b8d755d0ebe25f87edd262896108dfa2b073c0814093f7d2ebd8 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e48b3f70e18e77885fa9aacad3100d7678a827d00fb563dcd477899b1ee1d89e23ecb8f2999013a2043036cea9c6d61031e9c7b4162140f5829894388eee5bce7e93baee3ce0bf4190a0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba047e6e3ee18a0dcb8a530689f90df6155ccc5cb33a0b378c4885b36c315b435561f0ef42c5ba5a40979f0841216806b326e04a2da36a9011b2a694ff283f0fd98a630d79dbce95ab02 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f98369e9445c5882aa703756b77e75713ba3004075fa24c018653a1b4d103b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d842e68c723ec899be6e97299547bfae1c1c2666c328a4cc939f33d2be6eb3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3be70df2112be564394441fab73a3d1ea8cffbf282cb7e2fba6d4bf93eb3d0e546334907b6a75b27e91ddf1f4bb8265b68b7fea24bfbe6d185a29b30f2a103349aa2e37f6c2f1278168 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6538498df27580b5a8ce84806413a0bb3fef6548807b7675d415b295a3631293868d42d5504ab97a0d82a50cb83c2bf74206d4835e15686aa2abf992b7b0d27c5415c83cde596788278 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bd6813d28352fec1b43d31a7c1f39f37c4800d82a6281fcfc81eae0b97d3b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b1ea910350e67ec24ed0f3c557ff265133851bdafd4c7aea32ba5a7624f13 + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660d08c6ebb96e008cec2c0c4667d8488bfa63fb9542b9543bf2f44452ddfca2d7f2ef33da3c18e4950b1cfe62f4c883d97c018436fa3d37069cb5911316e08700 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4ce1063a2c24a067d32c33bc634f9164349ff4d51e2f736aa8ddfe7d85dbde +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e8ec223c4616b42db4b40ac577af6937537a779ffc4517314c4c90e6c6bec + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b63d4823ec3c33b747175212d3fa59c7320419f05114fa56bc49c588ce3efae0bd8ff356da1943afb6db2e8cb9fd67d0125c3c87b9c83ee8cce6e92d25387b4e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663960d18951259c9250ca1804369d267c7a61ba56041491bbe42dac780957c6c55061e844b5ab6cd23a97fee163cfb3db7b4faa27b08a1ca24b0a681294fe9bb1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9c8ed9bfe0b9016461bf4ab1d3f56b261cbd5f0c9a165184fcfbe28af3968 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81bfdb36c9b8d755d0ebe25f87edd262896108dfa2b073c0814093f7d2ebd8 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e48b3f70e18e77885fa9aacad3100d7678a827d00fb563dcd477899b1ee1d89e980889cb7bf25f6f4be3551e27e1ea7d9f2719d05e33dada3b7b1a5721c6142a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba047e6e3ee18a0dcb8a530689f90df6155ccc5cb33a0b378c4885b36c315b43ee2d0ae05c3381ef19d6552e4c379c9e3455f5369feb06f5b823512a752550a6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f98369e9445c5882aa703756b77e75713ba3004075fa24c018653a1b4d103b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d842e68c723ec899be6e97299547bfae1c1c2666c328a4cc939f33d2be6eb3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3be70df2112be564394441fab73a3d1ea8cffbf282cb7e2fba6d4bf93eb3d0e50d15abf5a511b499f4bb2364105d9762588d57b6b4cef7251a82d36e5a85394 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6538498df27580b5a8ce84806413a0bb3fef6548807b7675d415b295a3631299a0f8e43b9e338ca409665b3d31f4276ee5a9ba840a56170f1c28b57685cd310 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bd6813d28352fec1b43d31a7c1f39f37c4800d82a6281fcfc81eae0b97d3b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b1ea910350e67ec24ed0f3c557ff265133851bdafd4c7aea32ba5a7624f13 + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660d08c6ebb96e008cec2c0c4667d8488bfa63fb9542b9543bf2f44452ddfca2d7e7b3d10d1bec4db060cc81ac11981c86bd3886d3f59490443484f9dff1092bbff7dcf06981d28b28afaf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4ce1063a2c24a067d32c33bc634f9164349ff4d51e2f736aa8ddfe7d85dbde +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=1e8ec223c4616b42db4b40ac577af6937537a779ffc4517314c4c90e6c6bec + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b63d4823ec3c33b747175212d3fa59c7320419f05114fa56bc49c588ce3efae0bd8ff356da1943afb6db2e8cb9fd67d022e8eb3d61d2bb8d5009413d916e50ebf18eaeb1c662609b9507 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663960d18951259c9250ca1804369d267c7a61ba56041491bbe42dac780957c6c5196c019b9d174ed3dcaa53099503522a87381dbd1f2b9a676c27b5ac5b1513fbc5623bdc039536108225 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=b9c8ed9bfe0b9016461bf4ab1d3f56b261cbd5f0c9a165184fcfbe28af3968 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=81bfdb36c9b8d755d0ebe25f87edd262896108dfa2b073c0814093f7d2ebd8 + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e48b3f70e18e77885fa9aacad3100d7678a827d00fb563dcd477899b1ee1d89e980889cb7bf25f6f4be3551e27e1ea7d31e9c7b4162140f582989fb19a400cb8e233d3c9e389e6178779 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ba047e6e3ee18a0dcb8a530689f90df6155ccc5cb33a0b378c4885b36c315b4322b0f462158e15814a1bde609953f95db326e04a2da36a9011b27061e58c38b18c508dc98a28a96bd47d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f98369e9445c5882aa703756b77e75713ba3004075fa24c018653a1b4d103b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d842e68c723ec899be6e97299547bfae1c1c2666c328a4cc939f33d2be6eb3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c3be70df2112be564394441fab73a3d1ea8cffbf282cb7e2fba6d4bf93eb3d0e50d15abf5a511b499f4bb2364105d976b68b7fea24bfbe6d185a5c40f1b38412d69a8edfb30ae69c37b2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f6538498df27580b5a8ce84806413a0bb3fef6548807b7675d415b295a36312906e14d4e13ee44c451ac33dd85c6494674206d4835e15686aa2a956b0924d35a221d4b7181d71a7acb72 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8bd6813d28352fec1b43d31a7c1f39f37c4800d82a6281fcfc81eae0b97d3b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7b1ea910350e67ec24ed0f3c557ff265133851bdafd4c7aea32ba5a7624f13 + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b62d68267d71003dd2ec89177e7a80e3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=073e37ccc3b3b5f301022426e60a9fe42344451b0c246c7c3c52e90200becd +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=13d07f95326d21c8df6cc06e039928135e3e0ce76c0ac29c1af3af17f9f209 + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c7ecad40ae43136bb00e644faf111fee +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e80199955235b10ef537be4e4ece03b89e395270f354863329a81623fe31c4 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4223b3fdafd3b6e8362de55b3af3e442fe88d22174d266b7098f6d1f3d54dd + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625484bee855d8aaadb550fd7368ce11dae9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=44098386e9c10ee7805cd6c24acfa0e883439cab2955227546351f2d0b98d2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bbba498b110eeed6a4a8db59b425539b45f08454356ec2e9c332d77880488c + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254609e1a34b71f412922516c43c0e318eacbab4c4d9944d7320797 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=073e37ccc3b3b5f301022426e60a9fe42344451b0c246c7c3c52e90200becd +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=13d07f95326d21c8df6cc06e039928135e3e0ce76c0ac29c1af3af17f9f209 + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254acceaed8b3a21db94a655c36c11a60a8bb89df76cff84a34015e +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e80199955235b10ef537be4e4ece03b89e395270f354863329a81623fe31c4 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4223b3fdafd3b6e8362de55b3af3e442fe88d22174d266b7098f6d1f3d54dd + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c8a0cbbea89e5ae2aabf7a0ff0cab75f79795fe12ca51560061 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=44098386e9c10ee7805cd6c24acfa0e883439cab2955227546351f2d0b98d2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bbba498b110eeed6a4a8db59b425539b45f08454356ec2e9c332d77880488c + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419e9c7e045efa93cdbf8951bde24f518 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=073e37ccc3b3b5f301022426e60a9fe42344451b0c246c7c3c52e90200becd +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=13d07f95326d21c8df6cc06e039928135e3e0ce76c0ac29c1af3af17f9f209 + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625423626274f79a73c1a08d4f8b3740dc65 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e80199955235b10ef537be4e4ece03b89e395270f354863329a81623fe31c4 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4223b3fdafd3b6e8362de55b3af3e442fe88d22174d266b7098f6d1f3d54dd + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d7f8985f5a07f3b6134b3eb461d07c79 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=44098386e9c10ee7805cd6c24acfa0e883439cab2955227546351f2d0b98d2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bbba498b110eeed6a4a8db59b425539b45f08454356ec2e9c332d77880488c + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254609e1a34b71f412922514c3e94964753215ede1067c59472f88c +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=073e37ccc3b3b5f301022426e60a9fe42344451b0c246c7c3c52e90200becd +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=13d07f95326d21c8df6cc06e039928135e3e0ce76c0ac29c1af3af17f9f209 + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254acceaed8b3a21db94a65700f1c5dab0d3b1eac91132e3ab6eebe +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e80199955235b10ef537be4e4ece03b89e395270f354863329a81623fe31c4 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=4223b3fdafd3b6e8362de55b3af3e442fe88d22174d266b7098f6d1f3d54dd + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2b +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544c8a0cbbea89e5ae2aab126c87f8777b9b68d5b545fb3b2f398f +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=44098386e9c10ee7805cd6c24acfa0e883439cab2955227546351f2d0b98d2 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bbba498b110eeed6a4a8db59b425539b45f08454356ec2e9c332d77880488c + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bbe42ea4bcf66d6f758a4c188bf4bc91 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=084290d5043c3b6948d4921b6077beb8b735be5abb710c15d603fbe6a8837a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3bc6edaa3068acffde7c0e48a284fcc85e5a53eed67eebfc269b39a61d4fab + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a213fa659c7a882c575df816336d8be4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=4c0b6eb320ffdd0fc360e131a2743b8da960103c65a8574894dab9baebddbb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d78bbe8c396fcee4ec8845d3212997c19c03686fedd94fe7ad7083f8fccb1 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f14e85fd8ba7aba75b5a1a46a90667e1 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=393b40808649ae3cfe543634928e71fcc0db659c41c8a5bfa0463f8d097617 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=768b4c83f5e7bdf3236786bcaf620e2f72c314ee77dca21ea045a5e8ded973 + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549be6f2a5fceed9834cd66790fbc903926c448bc59b48b2154dd6 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=084290d5043c3b6948d4921b6077beb8b735be5abb710c15d603fbe6a8837a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3bc6edaa3068acffde7c0e48a284fcc85e5a53eed67eebfc269b39a61d4fab + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f6ab56ef38ff35798fe8f0f4d134086e57f446a2345b1191ea4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=4c0b6eb320ffdd0fc360e131a2743b8da960103c65a8574894dab9baebddbb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d78bbe8c396fcee4ec8845d3212997c19c03686fedd94fe7ad7083f8fccb1 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543bef9db972e2e6c71558809e51ae65d7420c45bdc240f8abd816 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=393b40808649ae3cfe543634928e71fcc0db659c41c8a5bfa0463f8d097617 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=768b4c83f5e7bdf3236786bcaf620e2f72c314ee77dca21ea045a5e8ded973 + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542b78acccc816e4c2f5f9699184235c74 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=084290d5043c3b6948d4921b6077beb8b735be5abb710c15d603fbe6a8837a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3bc6edaa3068acffde7c0e48a284fcc85e5a53eed67eebfc269b39a61d4fab + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254036e6f1d1a3deae5b6a6a0082f91b971 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=4c0b6eb320ffdd0fc360e131a2743b8da960103c65a8574894dab9baebddbb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d78bbe8c396fcee4ec8845d3212997c19c03686fedd94fe7ad7083f8fccb1 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542fba2f565d1471d00632cf0be54aaf62 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=393b40808649ae3cfe543634928e71fcc0db659c41c8a5bfa0463f8d097617 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=768b4c83f5e7bdf3236786bcaf620e2f72c314ee77dca21ea045a5e8ded973 + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549be6f2a5fceed9834cd62141f0bbf0f39ae2eac726587cc06702 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=084290d5043c3b6948d4921b6077beb8b735be5abb710c15d603fbe6a8837a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=3bc6edaa3068acffde7c0e48a284fcc85e5a53eed67eebfc269b39a61d4fab + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541f6ab56ef38ff35798feb9a0e6306cecfbf9d320ae214ca7ffa4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=4c0b6eb320ffdd0fc360e131a2743b8da960103c65a8574894dab9baebddbb +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0d78bbe8c396fcee4ec8845d3212997c19c03686fedd94fe7ad7083f8fccb1 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543bef9db972e2e6c71558a57e72719d6994322c7eba68ffb7ef1d +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=393b40808649ae3cfe543634928e71fcc0db659c41c8a5bfa0463f8d097617 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=768b4c83f5e7bdf3236786bcaf620e2f72c314ee77dca21ea045a5e8ded973 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544fd54b64a44cca6205b19aa279c8056ac51f96cf3d758067d237f87128e15a4c4148bd36ab1729cacb085be81f3480b4354206c59a07e41330ad15f95124cafa +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5876a3382ed90f78c1b3e6fcc88722443a39185cf5e5cda8ab5801aaf69cab +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=7c0c69826778f7c46a4a344ae33d3c0ed24c6d3be7fd57c2dc63ef4f23655f + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bb88bc8f1d5b95ff9b457b11932e08c4bf7737b9597e5dc4ced87cd5c0887080e2fee14b04294b61597f5e910bad3abf548e5e3e756da213e59a1707ed1994c5 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=27d554df29f82a035d188e8fac392e112e2155f4fb2d7efb097a7c4c92ae8b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=75d225f9a1c43f07a06f35ea7ad7ae7ca2e485fb080e7be7125995b7ca2263 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a613c9d0d0c7df0be15c578383f68146433aac97b59474cda1ba8aede82a04e58cd86fc4c305ad8471f0bfa4bc5cae2cd4cbf0bdcdcee3c1c7a411ede4b5cb19 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=38a911620b7d62cc36bdb2c5bd3f1f53c7b135ba945f890838208dd1ac3a60 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0687c7ac818efa9d4eb42085ac0531050094895a11ab5c62f4c49ff0f7da16 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544fd54b64a44cca6205b19aa279c8056ac51f96cf3d758067d237f87128e15a4c4148bd36ab1729cacb085be81f3480b4155fb51d817c41fe84d19fea4db898d03d6d178d62bb9d9673a0 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5876a3382ed90f78c1b3e6fcc88722443a39185cf5e5cda8ab5801aaf69cab +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=7c0c69826778f7c46a4a344ae33d3c0ed24c6d3be7fd57c2dc63ef4f23655f + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bb88bc8f1d5b95ff9b457b11932e08c4bf7737b9597e5dc4ced87cd5c0887080e2fee14b04294b61597f5e910bad3abf14a6559af2e96ddafc7e68c916704cffd7863bc38c69a17f28b6 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=27d554df29f82a035d188e8fac392e112e2155f4fb2d7efb097a7c4c92ae8b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=75d225f9a1c43f07a06f35ea7ad7ae7ca2e485fb080e7be7125995b7ca2263 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a613c9d0d0c7df0be15c578383f68146433aac97b59474cda1ba8aede82a04e58cd86fc4c305ad8471f0bfa4bc5cae2c4b81d112e3e7d0d726c849388581cc9b879a98224acb457c68b7 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=38a911620b7d62cc36bdb2c5bd3f1f53c7b135ba945f890838208dd1ac3a60 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0687c7ac818efa9d4eb42085ac0531050094895a11ab5c62f4c49ff0f7da16 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544fd54b64a44cca6205b19aa279c8056ac51f96cf3d758067d237f87128e15a4c7166621c380455d9dbf411bd450cdb4b05c3f2a27cbec817ffe9647f2a18afd9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5876a3382ed90f78c1b3e6fcc88722443a39185cf5e5cda8ab5801aaf69cab +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=7c0c69826778f7c46a4a344ae33d3c0ed24c6d3be7fd57c2dc63ef4f23655f + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bb88bc8f1d5b95ff9b457b11932e08c4bf7737b9597e5dc4ced87cd5c08870808e9bdae01e07f17b6fa915c3d91ed7d3547d6d73c86caa69fb94fed060c14382 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=27d554df29f82a035d188e8fac392e112e2155f4fb2d7efb097a7c4c92ae8b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=75d225f9a1c43f07a06f35ea7ad7ae7ca2e485fb080e7be7125995b7ca2263 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a613c9d0d0c7df0be15c578383f68146433aac97b59474cda1ba8aede82a04e544d764e5f67a403d442e16be3807b5d5f5f2bdf9e39234ca23c3a2d94b6c46f3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=38a911620b7d62cc36bdb2c5bd3f1f53c7b135ba945f890838208dd1ac3a60 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0687c7ac818efa9d4eb42085ac0531050094895a11ab5c62f4c49ff0f7da16 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544fd54b64a44cca6205b19aa279c8056ac51f96cf3d758067d237f87128e15a4c7166621c380455d9dbf411bd450cdb4b155fb51d817c41fe84d1c532e9d9b1ae823f499ea722badc77e4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=5876a3382ed90f78c1b3e6fcc88722443a39185cf5e5cda8ab5801aaf69cab +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=7c0c69826778f7c46a4a344ae33d3c0ed24c6d3be7fd57c2dc63ef4f23655f + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bb88bc8f1d5b95ff9b457b11932e08c4bf7737b9597e5dc4ced87cd5c08870808e9bdae01e07f17b6fa915c3d91ed7d314a6559af2e96ddafc7ed897a4125cd575976d0cdd5e33aca3fc +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=27d554df29f82a035d188e8fac392e112e2155f4fb2d7efb097a7c4c92ae8b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=75d225f9a1c43f07a06f35ea7ad7ae7ca2e485fb080e7be7125995b7ca2263 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2b +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a613c9d0d0c7df0be15c578383f68146433aac97b59474cda1ba8aede82a04e544d764e5f67a403d442e16be3807b5d54b81d112e3e7d0d726c8af41b189b719d2efe35796a636de31d9 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=38a911620b7d62cc36bdb2c5bd3f1f53c7b135ba945f890838208dd1ac3a60 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0687c7ac818efa9d4eb42085ac0531050094895a11ab5c62f4c49ff0f7da16 + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6b2af1b6bc7ab3bb3c96b892afbaf49 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e693375ca5a2a0ff37a4b36662433ecc789e8a04887751ac3b0bb070039726 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=821cbd91e90a763bc70ac3cdee3bd2fb4b9dcd0e7cc3a066b85811c0c55c10 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625429e02e0aff3585ba34213b02ce0584b1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667e40f02cbf3aba406c8b3556958221ef +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=45229f0fb23ccd92b0554c5be976ab8ccecf5f1e7503af4c5a1e4e45d35dd5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fcf39b68313e893f9682801d60aee12337d52a64661af37a0366b7924d1657 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540d6ecb3df1991eeb786683cac2d3f982 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660a5dcf3414a6c779bd8881e8852bc849 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ff900c6284287621348a3f116e7d1cb4fa64dffb7904a8332b36377381eafd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d49b01235ee41b7bb4b32de0b258be2280dcf68262b690fef7f0511bdb52d1 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254296fa023d848fab1af54ab8d08d37448 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b6e42d67d8cea5e983a691e0658fac72 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=98fd5ab58a3ad920b59dd500179a238f715af6d3b0d6d4a1801fad5e3c8dc5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4deac6ad723c4459d22e13e42c68b1b87c98cea7c470d684acd1c238be8398 + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669274a4f99ffbbcd930fb758f8ed76cc03fe9ad85a0fc5556f701 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e693375ca5a2a0ff37a4b36662433ecc789e8a04887751ac3b0bb070039726 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=821cbd91e90a763bc70ac3cdee3bd2fb4b9dcd0e7cc3a066b85811c0c55c10 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b8766d12729c594966e9e1234f04bdf152052d9085b3df49d3b9 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633188335572849c06f2196f49d512745d01ddf3748851abb18e5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=45229f0fb23ccd92b0554c5be976ab8ccecf5f1e7503af4c5a1e4e45d35dd5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fcf39b68313e893f9682801d60aee12337d52a64661af37a0366b7924d1657 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c65e819d0b4074ef005311ac1d8ddc01b50aec437a3e07b27f15 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466da135105806675a56c11b4d9eb8f1bf2f93503003b148160977b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ff900c6284287621348a3f116e7d1cb4fa64dffb7904a8332b36377381eafd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d49b01235ee41b7bb4b32de0b258be2280dcf68262b690fef7f0511bdb52d1 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c5cfd6799fc937000b5133e782ef3af066bce5532efe254878b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668a48263708b02a2508c92e6d37091d7805917886430d81cbf539 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=98fd5ab58a3ad920b59dd500179a238f715af6d3b0d6d4a1801fad5e3c8dc5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4deac6ad723c4459d22e13e42c68b1b87c98cea7c470d684acd1c238be8398 + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663116eefd4bce9076d9dcae0406a1e895 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e693375ca5a2a0ff37a4b36662433ecc789e8a04887751ac3b0bb070039726 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=821cbd91e90a763bc70ac3cdee3bd2fb4b9dcd0e7cc3a066b85811c0c55c10 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df955d65e85408302701c443b9876628 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466073acc4aae4797305f3a5014902f0389 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=45229f0fb23ccd92b0554c5be976ab8ccecf5f1e7503af4c5a1e4e45d35dd5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fcf39b68313e893f9682801d60aee12337d52a64661af37a0366b7924d1657 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543bc1046f99db530d13c0e9d8c4b8972a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d259d8e58663d8fdc8ee8a76f38aedb4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ff900c6284287621348a3f116e7d1cb4fa64dffb7904a8332b36377381eafd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d49b01235ee41b7bb4b32de0b258be2280dcf68262b690fef7f0511bdb52d1 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547b5ec929ff746b2951ad02dcb8e1d328 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f1470d8024e4f3ed2f729669ad158aed +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=98fd5ab58a3ad920b59dd500179a238f715af6d3b0d6d4a1801fad5e3c8dc5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4deac6ad723c4459d22e13e42c68b1b87c98cea7c470d684acd1c238be8398 + +handshake=Noise_NN_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669274a4f99ffbbcd930fb9d5f607de66556bd116615a94643140d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e693375ca5a2a0ff37a4b36662433ecc789e8a04887751ac3b0bb070039726 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=821cbd91e90a763bc70ac3cdee3bd2fb4b9dcd0e7cc3a066b85811c0c55c10 + +handshake=Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b8766d12729c594966e9df5831055ca8c424d8ca8f3f2a6fbeac +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633188335572849c06f2123581c51160861c0049f3bb291bd9e3f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=45229f0fb23ccd92b0554c5be976ab8ccecf5f1e7503af4c5a1e4e45d35dd5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fcf39b68313e893f9682801d60aee12337d52a64661af37a0366b7924d1657 + +handshake=Noise_NNpsk1_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c65e819d0b4074ef00531acf9a294d769a2eae079b342632d219 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466da135105806675a56c116abd2f66bf544bd00009d1f973865921 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ff900c6284287621348a3f116e7d1cb4fa64dffb7904a8332b36377381eafd +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d49b01235ee41b7bb4b32de0b258be2280dcf68262b690fef7f0511bdb52d1 + +handshake=Noise_NNpsk2_25519_ChaChaPoly_BLAKE2s +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549c5cfd6799fc937000b54a31dc936d6b1bd4e8676cdcc42b1bf3 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668a48263708b02a2508c97593c7ffd766732eba2768eab8536d6f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=98fd5ab58a3ad920b59dd500179a238f715af6d3b0d6d4a1801fad5e3c8dc5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4deac6ad723c4459d22e13e42c68b1b87c98cea7c470d684acd1c238be8398 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662996b770a8beee5210ae2ee2d93339cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=53437efbfb1f92fe43ae72099eb65358797dd48886cb9671975797e3f579ca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44bd43feee10b6715272dcc8826de7e866dc27f7e3dfb7148b4824eb226aea + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625406f76c7e9f1f456d70bf867e2c44a6c2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466f0b70f196c5e9dbe5bc086b4be3e425a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b98df9fba3f2887f5616371dbfeee8ee63dcc2830f8cf7a58ebf593ccf728 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d9d130f122419ba52d847d0099b0155e7e4ea9fe0ff4b4b2bef3a0f9bb75a + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b00aef15e78c2222b23f921a2940819b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846656bc91e33dd792081f01fe00c118bf9f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8f8dac7f5d54982068e3293e629a3ecdb58d6780b15240f4f9dd7157b04c3c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3bcd3a3be774bdaf617db13ae419cd4542b1d1796f7c3ef01f6dd56f210fa1 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254066270b88eaeaa86e505970da02d2c2c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668b803871150207af0a9bbb9a7532ff88 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e0a9264ac293727a86412dcb3c3293a0abf9283468cc94a78c30b457ae6e97 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4886d3f446d6daba42fc5eea04ccc91ed077abd0db4925ef076daf5b0f3cd4 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661cd505ea2a9f4ba454a661b2979075e9c575359c8f2543677d42 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=53437efbfb1f92fe43ae72099eb65358797dd48886cb9671975797e3f579ca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44bd43feee10b6715272dcc8826de7e866dc27f7e3dfb7148b4824eb226aea + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fdc73e2c2e717296f86029e72318cac7f1ffc79284aa8bd938cf +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846604563dac6ba8bdec8a444aa53f3da950706868979722e1df493a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b98df9fba3f2887f5616371dbfeee8ee63dcc2830f8cf7a58ebf593ccf728 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d9d130f122419ba52d847d0099b0155e7e4ea9fe0ff4b4b2bef3a0f9bb75a + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548aefbdd261500e340336114bd4696e9be890d9ff0fc44ea383c1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ae024a90f2448f1ee801f6cbe7b9b5999fcebe5c8c19366db677 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8f8dac7f5d54982068e3293e629a3ecdb58d6780b15240f4f9dd7157b04c3c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3bcd3a3be774bdaf617db13ae419cd4542b1d1796f7c3ef01f6dd56f210fa1 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541798c5f0ce19bfeeb8e18af1f7646b1f78b4e2fe25e9c4aa503f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b4179026203db247901b5b2ad69041a6c10a2c5c39b06f619c7e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e0a9264ac293727a86412dcb3c3293a0abf9283468cc94a78c30b457ae6e97 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4886d3f446d6daba42fc5eea04ccc91ed077abd0db4925ef076daf5b0f3cd4 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846667203848cd4c9ae0b133522056dba949 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=53437efbfb1f92fe43ae72099eb65358797dd48886cb9671975797e3f579ca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44bd43feee10b6715272dcc8826de7e866dc27f7e3dfb7148b4824eb226aea + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662540949d3d2cd0eaca6b6506a09b263fe4a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664404e85e9fb434e0d2218ff52fe95fd7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b98df9fba3f2887f5616371dbfeee8ee63dcc2830f8cf7a58ebf593ccf728 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d9d130f122419ba52d847d0099b0155e7e4ea9fe0ff4b4b2bef3a0f9bb75a + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f0f5d97c2da7cf61e0d3948154ba74e4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466099137f9449e7fa478c3ed1fdab515ea +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8f8dac7f5d54982068e3293e629a3ecdb58d6780b15240f4f9dd7157b04c3c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3bcd3a3be774bdaf617db13ae419cd4542b1d1796f7c3ef01f6dd56f210fa1 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254098b9b5f3f97855bdbf6058d616bfe58 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ed1898e3f24678b9217c3c2ce1cfb437 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e0a9264ac293727a86412dcb3c3293a0abf9283468cc94a78c30b457ae6e97 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4886d3f446d6daba42fc5eea04ccc91ed077abd0db4925ef076daf5b0f3cd4 + +handshake=Noise_KN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661cd505ea2a9f4ba454a673b09a4a33ce505f13351254cce920a6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=53437efbfb1f92fe43ae72099eb65358797dd48886cb9671975797e3f579ca +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=44bd43feee10b6715272dcc8826de7e866dc27f7e3dfb7148b4824eb226aea + +handshake=Noise_KNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fdc73e2c2e717296f860f1ce209564649b4c8c5b08a054956d53 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846604563dac6ba8bdec8a44ca483cb93b9ae929ac1d197021cf2085 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8b98df9fba3f2887f5616371dbfeee8ee63dcc2830f8cf7a58ebf593ccf728 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d9d130f122419ba52d847d0099b0155e7e4ea9fe0ff4b4b2bef3a0f9bb75a + +handshake=Noise_KNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548aefbdd261500e340336f649ecfec1f202ce87c63b9ebcf86561 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ae024a90f2448f1ee801ea786081533c8eb3243d2bf0d737ba6c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=8f8dac7f5d54982068e3293e629a3ecdb58d6780b15240f4f9dd7157b04c3c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=3bcd3a3be774bdaf617db13ae419cd4542b1d1796f7c3ef01f6dd56f210fa1 + +handshake=Noise_KNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541798c5f0ce19bfeeb8e177a3c5e381a60f5e06de14a6e67d0371 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b4179026203db247901b1e7fb2131d14bfa00e9a72203580ecee +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=e0a9264ac293727a86412dcb3c3293a0abf9283468cc94a78c30b457ae6e97 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=4886d3f446d6daba42fc5eea04ccc91ed077abd0db4925ef076daf5b0f3cd4 + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c796bf92e018434c9b2146fab78f30d0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cb3abc71944afc6463300a32ba99b33d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=56a475d3db0d0d5931542a93e3cd57c7dc51b29fc6d0a7cea41aea05d99fe5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c239eb65b5f0d0641f6c6c20aec65646626249f9194e4211a2f8e761c2d72 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c9047e5f60f5b21c65fa8ff35c46e4f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466cf1d49363de74d70a9f0cdbaa3310eda +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6593eb8dd060da72b612dd4128b4fef345d58c2e8cc2764dff574a3094fe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7ce16bfa101adc89a7773ffd08c545634f59d9035cabadef5f5ce941351d4 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625444240d38699667b5d6c608f41fdee5a6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661379efd5a3414a48873a1d9b88af74a7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2e97c7a30baa66eb2eef35ac21f0985cb7139c68c681119ac87dd8864ab50e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2d441a28146d89109afcebf7fb254715a4937c1b775ed048735c301b7c15ba + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f944f03a16bec0d4ede15bbf507f7e25 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846634632482a2c45167231236b170f1fbc1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=93bb4e3dd1995295277446d3010fc7299dd2d1f283d7ce9ee8934d1caa60ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d7ce2e01658cebe3086b25ae67c184cbb26e4855bc9c03a82c149948ea9a4e + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bc7e9bcabcd39b9278b329a24d91072a9948a6cab4205f4c2d25 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466060fcddff00afaa37fd10ae19782d5eda54dc6d0af0a1ae34816 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=56a475d3db0d0d5931542a93e3cd57c7dc51b29fc6d0a7cea41aea05d99fe5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c239eb65b5f0d0641f6c6c20aec65646626249f9194e4211a2f8e761c2d72 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544e94ec05dc68a1daa22d31bf607f134c66047ce9b78516559d77 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466281b734b3aba9427cddf7bb7d3165127146b88235d7d9f276e66 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6593eb8dd060da72b612dd4128b4fef345d58c2e8cc2764dff574a3094fe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7ce16bfa101adc89a7773ffd08c545634f59d9035cabadef5f5ce941351d4 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b844c29336d91edab89a73e74bb4a4964c09b0449b950f67ede8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660e1784da1b96e7a4a7d7bee4668e1c37f9e61052c4553d7a1339 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2e97c7a30baa66eb2eef35ac21f0985cb7139c68c681119ac87dd8864ab50e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2d441a28146d89109afcebf7fb254715a4937c1b775ed048735c301b7c15ba + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c1384003bc26279ca3c0030d4aaf3b3dd795108bd34df2f6607 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663780ee06ece35bbfb120e4f2070358151d0642cb542d816754a5 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=93bb4e3dd1995295277446d3010fc7299dd2d1f283d7ce9ee8934d1caa60ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d7ce2e01658cebe3086b25ae67c184cbb26e4855bc9c03a82c149948ea9a4e + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c25868d2b2a31aa03b91b342e3a0f010 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d3bd657df804422777533bd275e14c99 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=56a475d3db0d0d5931542a93e3cd57c7dc51b29fc6d0a7cea41aea05d99fe5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c239eb65b5f0d0641f6c6c20aec65646626249f9194e4211a2f8e761c2d72 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544490043bc9ee1f9b37b487bd5c239c9f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846659153640b1bffc0da68baa51d62f821c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6593eb8dd060da72b612dd4128b4fef345d58c2e8cc2764dff574a3094fe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7ce16bfa101adc89a7773ffd08c545634f59d9035cabadef5f5ce941351d4 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d438f5822dfd27a43ada58efc5977708 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466117ef4bc881b704cfb87d2c0e95fa683 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2e97c7a30baa66eb2eef35ac21f0985cb7139c68c681119ac87dd8864ab50e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2d441a28146d89109afcebf7fb254715a4937c1b775ed048735c301b7c15ba + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae324e3db885a891345f300591c39991 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466158ae4d81ce5d413184b62ecbf1db7d6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=93bb4e3dd1995295277446d3010fc7299dd2d1f283d7ce9ee8934d1caa60ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d7ce2e01658cebe3086b25ae67c184cbb26e4855bc9c03a82c149948ea9a4e + +handshake=Noise_NK_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254bc7e9bcabcd39b9278b37f9892f7dec16e155389121da24e1fad +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466060fcddff00afaa37fd11c440d18031d7f9a735d2dd1ea6bfe24 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=56a475d3db0d0d5931542a93e3cd57c7dc51b29fc6d0a7cea41aea05d99fe5 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c239eb65b5f0d0641f6c6c20aec65646626249f9194e4211a2f8e761c2d72 + +handshake=Noise_NKpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544e94ec05dc68a1daa22de47ad3b7f3e2e17d0b302fa6890ea67f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466281b734b3aba9427cddf3c94b9f572f110a02b5e52acab758e34 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a6593eb8dd060da72b612dd4128b4fef345d58c2e8cc2764dff574a3094fe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b7ce16bfa101adc89a7773ffd08c545634f59d9035cabadef5f5ce941351d4 + +handshake=Noise_NKpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b844c29336d91edab89a43bfc3fe933ccd161c24839025e6c72d +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660e1784da1b96e7a4a7d743449335246823acd49e72750ccfa6fa +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=2e97c7a30baa66eb2eef35ac21f0985cb7139c68c681119ac87dd8864ab50e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=2d441a28146d89109afcebf7fb254715a4937c1b775ed048735c301b7c15ba + +handshake=Noise_NKpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c1384003bc26279ca3cb125ee90cc218132fdbf93455a891a92 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663780ee06ece35bbfb120dda59c0d7f0226547003e9db0016a4ab +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=93bb4e3dd1995295277446d3010fc7299dd2d1f283d7ce9ee8934d1caa60ef +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d7ce2e01658cebe3086b25ae67c184cbb26e4855bc9c03a82c149948ea9a4e + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d8021192b02d5946c7e1e789d60c9c06 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466388958d71fa742cfe4c44b889e03b468 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=674d3b19a02535626dfcb13bd383509b715566cf53e9f31ac161944d38b7c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=aefd829d861f03d0d8c4bfedbb520f7c1837a46e2e1b26896063783b1cba4b + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625402790d4c1ebce1325c633c1f1ea80ad4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe65d3f16b8c5ccf188f663b2183c2fd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42e238b4b6180654120bdb79734c6bbf8d47cc49f94689740b89443a5f809c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=556615110f73692755058a5f80d58f952a3eecccd14006edf6dcff48f44b5a + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a8a2e2a6065a7666ddee18705efd8639 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b3385c8f08a91f06deff7077b00932f4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19e26089ed5d9ec2cd5a9488c012880c76670e7b6ef405e518a658008f829c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32a0cd0ddbbe90796cde8048bc59f2c3544948b03e6675e4ae0437baf0df06 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254eace755c4d02a6492ec15bc6fb76ca61 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846637b28fc3206f049e0d7ee41b124c12dd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0136e8d63fc19792c4a64e752e7de2ee2b61eb0ae0298595363785c8f653d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fbb11e69ee5a33728ed2823c05a6fa19dc7d73d6af4467e990e87941bd582f + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419aad3185cdd8cf655a1e5c3dd7a90657bf4c873bac45f7f8225 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668f22a41cfad6486600f09fe2698e50cc3657fc2261cd5b29f73c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=674d3b19a02535626dfcb13bd383509b715566cf53e9f31ac161944d38b7c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=aefd829d861f03d0d8c4bfedbb520f7c1837a46e2e1b26896063783b1cba4b + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c98a7a53fef3f35c47556529a7f0d50cb2a15c56501f76d59e09 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666d587d79056823bbadec39dee9aa9580e4f45bcf104f273ea3b1 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42e238b4b6180654120bdb79734c6bbf8d47cc49f94689740b89443a5f809c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=556615110f73692755058a5f80d58f952a3eecccd14006edf6dcff48f44b5a + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543deac12a288a3ffb2541fd331a5da4e660281d6803a335926020 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846639f393a7a74357488e1fbb252c4678b320a0f82ec35209798870 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19e26089ed5d9ec2cd5a9488c012880c76670e7b6ef405e518a658008f829c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32a0cd0ddbbe90796cde8048bc59f2c3544948b03e6675e4ae0437baf0df06 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254935aac7f2c79135a1ae9ad51b5ce8d469acc4b9630f97992db02 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b1b80dee04d5354522d814e28e9e074e1cd71345e2fe6c0e8725 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0136e8d63fc19792c4a64e752e7de2ee2b61eb0ae0298595363785c8f653d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fbb11e69ee5a33728ed2823c05a6fa19dc7d73d6af4467e990e87941bd582f + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625494c0722b15726c73e42293762f1f231b +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668b06fbd531249a47de97b5d0a1d28204 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=674d3b19a02535626dfcb13bd383509b715566cf53e9f31ac161944d38b7c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=aefd829d861f03d0d8c4bfedbb520f7c1837a46e2e1b26896063783b1cba4b + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df63a84e581cf0ee95c5bee20b388692 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9172f26d7b9526845b62124cc08260e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42e238b4b6180654120bdb79734c6bbf8d47cc49f94689740b89443a5f809c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=556615110f73692755058a5f80d58f952a3eecccd14006edf6dcff48f44b5a + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546b84654df558648f7477ce7e3408ce12 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe1815dab93dffb8ae0b5f9134ddc4de +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19e26089ed5d9ec2cd5a9488c012880c76670e7b6ef405e518a658008f829c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32a0cd0ddbbe90796cde8048bc59f2c3544948b03e6675e4ae0437baf0df06 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545f1e8dfaa017156a4d6b5d8c99129763 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466902a71bf779743a6844bd76f6c8bf029 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0136e8d63fc19792c4a64e752e7de2ee2b61eb0ae0298595363785c8f653d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fbb11e69ee5a33728ed2823c05a6fa19dc7d73d6af4467e990e87941bd582f + +handshake=Noise_KK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625419aad3185cdd8cf655a139d31873c6117854954b8fd22d9e6489 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668f22a41cfad6486600f0fbb4ae670da71c5206d2817405a505d7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=674d3b19a02535626dfcb13bd383509b715566cf53e9f31ac161944d38b7c1 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=aefd829d861f03d0d8c4bfedbb520f7c1837a46e2e1b26896063783b1cba4b + +handshake=Noise_KKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c98a7a53fef3f35c4755296b675ec07df2f17c802c6264ef8d4a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666d587d79056823bbadec72c5647701d2468995235e0e2dfa6130 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=42e238b4b6180654120bdb79734c6bbf8d47cc49f94689740b89443a5f809c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=556615110f73692755058a5f80d58f952a3eecccd14006edf6dcff48f44b5a + +handshake=Noise_KKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543deac12a288a3ffb25418beeca17308cd9c7c9931d1ab774f12f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846639f393a7a74357488e1f1ba5d4c24b572488251c32b03de1ab63 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19e26089ed5d9ec2cd5a9488c012880c76670e7b6ef405e518a658008f829c +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=32a0cd0ddbbe90796cde8048bc59f2c3544948b03e6675e4ae0437baf0df06 + +handshake=Noise_KKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254935aac7f2c79135a1ae93f52e8f9b4b46fb2393b2bdacb48565c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b1b80dee04d5354522d85eed0973dca2d7cee4415256eac4724d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=a0136e8d63fc19792c4a64e752e7de2ee2b61eb0ae0298595363785c8f653d +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=fbb11e69ee5a33728ed2823c05a6fa19dc7d73d6af4467e990e87941bd582f + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fa9441324a92794acc0183591dd9d557e9d2251ff81cb8e7b6a34939ac4036f7d53a2007a3c8f072b93fd48bc802cb515be42a451820b25defc737ce7e3a02e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab1d23a9f710a0149ddbb596f968be2ed7afbdc065d8fed5168472f4e0c263 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=173b29d07b7e78108bab3bf145eba669861543b85910a5d60e101d1b57ca02 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254fbe8dfe276679b474bd9e513b64634df +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e15aaba5d9237372cd606332278a7fafe502bf5da959448b7aba91aa233b84269c46c3dc622e69a9460016f8e316da4ce33ff43f9a694008b6ea9c4733b37c5b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d669f1665b76c5081948c04c3f8fcdadbedb03fc0bf735bccead480c9d07d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f1bbc916980b6e57f5c73900c8c3a59e793ec656a08153f0907ddd48c32656 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f921f0b4cdcc7390e29c00352a70c592 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c275a8088f895e9da65446a1e0f546af2cb58f8ca255a901d607c04862c05d4e714660c2232771711e2f32a3d7d1fc99b177e7ea52743ae3aff0ac71c858c32d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6d6afdf7b42a9b89cb2d10db38215064e496f4a7b4a6ed07a6c3ca9079121b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22fa156f8584ac9649c136dc97aadc118b2228ead75adb7a613bad01296099 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625456287ced9403b4417a01582209846ee8 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1cd0d53bab3c8076ab5f5c8dc0b79628e1e24b179f2b9e83dd9a891c527a2381bfb9a4a59efab9610fe21a425f698732f6a98356e740fb037f721ba9858e9b9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0ca7d068c7d39806366bbf7e93af4348300523ce01d7e96c89de8e4fbb9ca8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a7675930bc1cefe9a1f84f535b3b583cefcfac329838e7bb176f226570f7a6 + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fa9441324a92794acc0183591dd9d557e9d2251ff81cb8e7b6a34939ac4036f40ffb1456c9e640da7023f3fd1a4082eb2be7bcc73a2ab41fc9d67482e64e47f175e3ab4b97fda1ff7cf +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab1d23a9f710a0149ddbb596f968be2ed7afbdc065d8fed5168472f4e0c263 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=173b29d07b7e78108bab3bf145eba669861543b85910a5d60e101d1b57ca02 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549466b62462582414c580a5d26559f913770e8ff43e82d1d11c2a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e15aaba5d9237372cd606332278a7fafe502bf5da959448b7aba91aa233b8426256c0bce8d8a8a48e6749218b6bf4d1fbc50c9616d0018183df12bc6a32a5ae685e786e15ae420fdf1ea +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d669f1665b76c5081948c04c3f8fcdadbedb03fc0bf735bccead480c9d07d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f1bbc916980b6e57f5c73900c8c3a59e793ec656a08153f0907ddd48c32656 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dbd5e20809d301052b4953b63dab04cbb1bdca9ce948132bc6a1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c275a8088f895e9da65446a1e0f546af2cb58f8ca255a901d607c04862c05d4e24b1f1a06cbbd9ca58c102cf6df58054a0cc0aee27153e563b6628d04492ddabf898e9d3dc88cb05caf9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6d6afdf7b42a9b89cb2d10db38215064e496f4a7b4a6ed07a6c3ca9079121b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22fa156f8584ac9649c136dc97aadc118b2228ead75adb7a613bad01296099 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625414fde92796c7eb025037438eeacbdcb2c0c94f049ba861860b0e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1cd0d53bab3c8076ab5f5c8dc0b79628e1e24b179f2b9e83dd9a891c527a238ba5e4798d9a8c59fe6c7a32b28904c7c29b8a81fc40825e8f546253cd908c607f8a37a276f13e12db216 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0ca7d068c7d39806366bbf7e93af4348300523ce01d7e96c89de8e4fbb9ca8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a7675930bc1cefe9a1f84f535b3b583cefcfac329838e7bb176f226570f7a6 + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fa9441324a92794acc0183591dd9d557e9d2251ff81cb8e7b6a34939ac4036f8651a0e993975aeea53e4113ada3b7d80688689fa70e534841d31e505db9fc63 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab1d23a9f710a0149ddbb596f968be2ed7afbdc065d8fed5168472f4e0c263 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=173b29d07b7e78108bab3bf145eba669861543b85910a5d60e101d1b57ca02 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541c6e2b9c9a65d9194cb1f369e1afd5e4 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e15aaba5d9237372cd606332278a7fafe502bf5da959448b7aba91aa233b842681582921e2a265120960fdd7a5c4863d4c3ca740b0fdea11e84d42a79641712c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d669f1665b76c5081948c04c3f8fcdadbedb03fc0bf735bccead480c9d07d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f1bbc916980b6e57f5c73900c8c3a59e793ec656a08153f0907ddd48c32656 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254acd1745c885149a64ce7f3481dee508a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c275a8088f895e9da65446a1e0f546af2cb58f8ca255a901d607c04862c05d4e2bc44f07f0001ff465418b2180d8b01c70915587643ff6e707d27eb1203bebf0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6d6afdf7b42a9b89cb2d10db38215064e496f4a7b4a6ed07a6c3ca9079121b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22fa156f8584ac9649c136dc97aadc118b2228ead75adb7a613bad01296099 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254435325bcaf808e2b1a57d1e0cfadda3a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1cd0d53bab3c8076ab5f5c8dc0b79628e1e24b179f2b9e83dd9a891c527a238e295e298959aeaec8ba42bb0c2fccc99632cbcccec4341a272657bbb1e6589bd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0ca7d068c7d39806366bbf7e93af4348300523ce01d7e96c89de8e4fbb9ca8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a7675930bc1cefe9a1f84f535b3b583cefcfac329838e7bb176f226570f7a6 + +handshake=Noise_NX_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662fa9441324a92794acc0183591dd9d557e9d2251ff81cb8e7b6a34939ac4036fbd4d474a60b9243549e661a23fbe6818b2be7bcc73a2ab41fc9dc20c5b432f6d1d06b2f0d17c51070d3a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=ab1d23a9f710a0149ddbb596f968be2ed7afbdc065d8fed5168472f4e0c263 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=173b29d07b7e78108bab3bf145eba669861543b85910a5d60e101d1b57ca02 + +handshake=Noise_NXpsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549466b62462582414c580478ce9b85bd9aa77e54f67f4dd6c5d82 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e15aaba5d9237372cd606332278a7fafe502bf5da959448b7aba91aa233b84269fc00380622f9c2cbdcac0ed827cdd4cbc50c9616d0018183df16dc0cdbe1194bbeb74960015ce712022 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d669f1665b76c5081948c04c3f8fcdadbedb03fc0bf735bccead480c9d07d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=f1bbc916980b6e57f5c73900c8c3a59e793ec656a08153f0907ddd48c32656 + +handshake=Noise_NXpsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dbd5e20809d301052b493609a928ec2fe986655186f645a7791c +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c275a8088f895e9da65446a1e0f546af2cb58f8ca255a901d607c04862c05d4e7fbc9e638653a16fd2d3f653dc377ccca0cc0aee27153e563b668fcabf727f2fe6d5dd0dda9dd235599d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6d6afdf7b42a9b89cb2d10db38215064e496f4a7b4a6ed07a6c3ca9079121b +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=22fa156f8584ac9649c136dc97aadc118b2228ead75adb7a613bad01296099 + +handshake=Noise_NXpsk2_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625414fde92796c7eb025037e305fb9a4b18616d971a36b6852f7315 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a1cd0d53bab3c8076ab5f5c8dc0b79628e1e24b179f2b9e83dd9a891c527a238b0b828d5c244b4c3c239b1c7b2ddbab729b8a81fc40825e8f5466d7e958a84ff6b12e1af4fbba9a29b50 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=0ca7d068c7d39806366bbf7e93af4348300523ce01d7e96c89de8e4fbb9ca8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=a7675930bc1cefe9a1f84f535b3b583cefcfac329838e7bb176f226570f7a6 + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664da461bfc2d7e228776700246eecb12bc654b92fef771afb5c6c6645648e11d847f40b2d552be046c38b3882103e86fc283c15084a8b61fd16d83e556498ec48 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f2705e50e8767f26211b34d7fed7756365369d16d09beb7c2242bf73344bdf +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d5a714198d09c66a53b7430a506394c4fc09cf01ba87a63be5cc6a3950971 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a708d17c82987917466c1283e27a5243 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dade0aaee91efc2a450b6473fb57348ce567f479f3434272157f7a1c1e9c910c7561bf41b5d645b6ddc9fed8e78bee6123322e497d2a8304888aadfdf2827cac +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=37146cfbb188da3bfa49c5395f5efe6192d71715dad654f752818b62cd4cf8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c1087fdfc98033ebd073c253f5cd07c491e345b60eb2db754b6081bda1264 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541b2c9cd52bff4bc2f41a75e8e23b4eed +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633507ddc0579de7fbe76c684d63e57d543196a324296bc48cd1c7c4573daf945cf06ccbe204667df4aceffdeb4414bf94d1357942e5206de77985c5cdd40844e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1b7d27ab5b443523ae268ca3d793470450e01704618a971ca391b115ac6c98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=62ea5681b380e2a9c1a386ba08bca2ded5a8a6f596841dacce9d9f25c51ad1 + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e3680648d1d20449b7c0aea4203871b0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b217bad95312cabcc05c2faa1d4c06b0e11b9dcb71f1e37e6970a55e24352b61482a9701a39f039df362b5cbc297a1b5b5769b45d14697675b25c72ec6f41fb6 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c63441220a5aea59a924dc2f03c5f19d6dbf065d3f1fbeffb8c2a9443eba4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=12296e1c0a21fd13cbe935d4bff4855f097bfa6b56a5220b8bed38c222a82b + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664da461bfc2d7e228776700246eecb12bc654b92fef771afb5c6c6645648e11d85f7ae53e16f2f8b10e6f6f77e6b737d17e65818a7649a0dd819b8b79f1e8aadf3dab7f4ccfdb86dbd5b4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f2705e50e8767f26211b34d7fed7756365369d16d09beb7c2242bf73344bdf +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d5a714198d09c66a53b7430a506394c4fc09cf01ba87a63be5cc6a3950971 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aa9944ef5862e98b59774e7c724731a7c9ad55bb23e759b6155e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dade0aaee91efc2a450b6473fb57348ce567f479f3434272157f7a1c1e9c910c26475971134b2de5ed2acfcc024a4126fa5a09cfc607150eab573e9d106f9c538e33d45efaa6f7bcb45e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=37146cfbb188da3bfa49c5395f5efe6192d71715dad654f752818b62cd4cf8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c1087fdfc98033ebd073c253f5cd07c491e345b60eb2db754b6081bda1264 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254852022ca0041d1875ce9c1e0a87166a72b54e2be548b4fb70b10 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633507ddc0579de7fbe76c684d63e57d543196a324296bc48cd1c7c4573daf945617479de0875fba178c5c9adf3280df5cfc231db12d274de858364a5245306776132c263d487322b63f8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1b7d27ab5b443523ae268ca3d793470450e01704618a971ca391b115ac6c98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=62ea5681b380e2a9c1a386ba08bca2ded5a8a6f596841dacce9d9f25c51ad1 + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254db02872b3c4193584b69762d97fb9f89abbdd582b7f8e5dc6e22 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b217bad95312cabcc05c2faa1d4c06b0e11b9dcb71f1e37e6970a55e24352b612c433e36f398b4e463e0d77434f8ad9e7ed2ee1f9beeed0a3e868ad2d0f36605870fbacd13fae104a316 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c63441220a5aea59a924dc2f03c5f19d6dbf065d3f1fbeffb8c2a9443eba4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=12296e1c0a21fd13cbe935d4bff4855f097bfa6b56a5220b8bed38c222a82b + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664da461bfc2d7e228776700246eecb12bc654b92fef771afb5c6c6645648e11d8b0cfe2f8e48e009af03e6420e5f0dfab42491c7c224bb630b73d159ef7ff18a8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f2705e50e8767f26211b34d7fed7756365369d16d09beb7c2242bf73344bdf +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d5a714198d09c66a53b7430a506394c4fc09cf01ba87a63be5cc6a3950971 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625467be4845bb485599879d5d2744ffc023 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dade0aaee91efc2a450b6473fb57348ce567f479f3434272157f7a1c1e9c910c8cd74cab21809c5bf9ae94a3e74d9bd17fafd70a1360983530c8574e62567f74 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=37146cfbb188da3bfa49c5395f5efe6192d71715dad654f752818b62cd4cf8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c1087fdfc98033ebd073c253f5cd07c491e345b60eb2db754b6081bda1264 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a32d10e5390ce2550ad276761ef7889f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633507ddc0579de7fbe76c684d63e57d543196a324296bc48cd1c7c4573daf945c1ee27fed069cbac9996f122e1180aabed9b592cbde022e46d84a11941ec1527 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1b7d27ab5b443523ae268ca3d793470450e01704618a971ca391b115ac6c98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=62ea5681b380e2a9c1a386ba08bca2ded5a8a6f596841dacce9d9f25c51ad1 + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a8e1f464d3fd4aca7a283f32c0d816e2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b217bad95312cabcc05c2faa1d4c06b0e11b9dcb71f1e37e6970a55e24352b61c7fe2e8c86a9322bb9d26850cf0727c55e3172f310413bb5addfba93df599150 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c63441220a5aea59a924dc2f03c5f19d6dbf065d3f1fbeffb8c2a9443eba4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=12296e1c0a21fd13cbe935d4bff4855f097bfa6b56a5220b8bed38c222a82b + +handshake=Noise_KX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664da461bfc2d7e228776700246eecb12bc654b92fef771afb5c6c6645648e11d8d792d9531d4982940eb0f25d701902557e65818a7649a0dd819b2669d91c8e90827d6252b0855edaee1c +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=f2705e50e8767f26211b34d7fed7756365369d16d09beb7c2242bf73344bdf +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5d5a714198d09c66a53b7430a506394c4fc09cf01ba87a63be5cc6a3950971 + +handshake=Noise_KXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254aa9944ef5862e98b5977fc452078277dd82650680c3709420ece +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466dade0aaee91efc2a450b6473fb57348ce567f479f3434272157f7a1c1e9c910cf73243ef2c5e6e04886629ee23126d86fa5a09cfc607150eab57ab0e1c47090e4d87caebb8180cc5dcde +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=37146cfbb188da3bfa49c5395f5efe6192d71715dad654f752818b62cd4cf8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=5c1087fdfc98033ebd073c253f5cd07c491e345b60eb2db754b6081bda1264 + +handshake=Noise_KXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254852022ca0041d1875ce967af157e5a16f3b94544b7e3f6559950 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846633507ddc0579de7fbe76c684d63e57d543196a324296bc48cd1c7c4573daf9450e09353924859de4e199926441bb4f4fcfc231db12d274de858332825a59715f48ae8b81da85503919df +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=1b7d27ab5b443523ae268ca3d793470450e01704618a971ca391b115ac6c98 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=62ea5681b380e2a9c1a386ba08bca2ded5a8a6f596841dacce9d9f25c51ad1 + +handshake=Noise_KXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254db02872b3c4193584b69e13c7bfd4702fbbf8be5dec60f1f1a2b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b217bad95312cabcc05c2faa1d4c06b0e11b9dcb71f1e37e6970a55e24352b617c6c0a311097ecff8bb1f324e9802f137ed2ee1f9beeed0a3e869b49f84fc648bc5733d5fe944589a4f0 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=4c63441220a5aea59a924dc2f03c5f19d6dbf065d3f1fbeffb8c2a9443eba4 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=12296e1c0a21fd13cbe935d4bff4855f097bfa6b56a5220b8bed38c222a82b + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667c3bcb8aa57d16c472e5884f7f10d713 +msg_2_payload= +msg_2_ciphertext=3fd53af07c2c674ca7cf182726641c4c02d7c8d3b0dfecdafecf43b741fac77b9cb60225da2079f22ff4bd57a995175986d65b89a24315d2300e04f08b1214c3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3907e2136f0103c819943689cceace3d4f5428bedab749d25ae8afdaf5ef74 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=99cce8f25e45b84ea11bb53afa95131a80faed0345ed3f328b830166eaed5a + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e536bf7659b705b260e11326d088608d +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466384980e3852095d08dd4418f4b9d766a +msg_2_payload= +msg_2_ciphertext=f336d406e1f75f3ffd3865c92ce137c55e37dc49e27210e05254c2ec3ad7ee4a1199e9838d05b8562d459f0be3ed09e900a3967b6ac1bf68178cbf4f4f521b9f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dee33db18e140806fbdc44c4f3b2d7860948d4cc1938dae2dd41e13146756d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=284090b027f87c4dd51fe38650b3703a08b06dd9022e6d2ffc7f2b04a28459 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d5bdd95205c45c1e7b522000e02ae624 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667ac2f4af89e151b584a2b7cedf3b98af +msg_2_payload= +msg_2_ciphertext=0d06059800951529977ab99abf46011735b52bc602ed118b505e013091719a081d41709ebae85b753a5e4a220c6de5a175240be1b0ff56d32ccd60374d607b55 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0d616739d9678ba60390dfb5a27c4f636820ea559fcd84a049ce5c785cbee3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6f68ab6c0bffe6cebc38e8351dbd50541a4e645e765db0b3582db6711216e2 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545ced8cfad93ee839f831bf40f350d394 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846636c9388f83f1d795eba433e3a85f6b71 +msg_2_payload= +msg_2_ciphertext=6ffc44aa06250c17e707f2496732412ed194ea271ed8d0db223b9db3cec1719c4ee79d0d034be157e33048185c964495b331be70f390d09d6d63b7d21b3bc0cf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1d203dde50bb9c29b43ea61990dc7f33af190af9c04ca8e2dde93314f17e83 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=78be8aa2d277eb4e3dfb5e3f8de1b46b8bf8a0369ed052fde5c5ddb35f3d1b + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662549ab9834e132b8bb4879a23b62843fcbf +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bb3e012f72892b7e941bce96ca2ea563 +msg_2_payload= +msg_2_ciphertext=c533dd475d8136b5aeaa4c5113f90ad850eb9f23b6b4c6101f361d28ae49237bdfd0f3ef74d4d4dba6327fde952c82d924aa3af517292ccf6a663aedafb523ae +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e2eac4b51925c4c1a6d132387b7e72cdb73d43a28e5a77d0792fa9741803ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=bd4e9d62222743b195d68b066ec04f67fdc2303d73abf6fbd9a2256d3a03aa + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846668e545d2dc0b6d33da9fd24ad31b9b33f8a2bd66c94ffc254f41 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3fd53af07c2c674ca7cf182726641c4c02d7c8d3b0dfecdafecf43b741fac77bcfa35e90e3132d80034ed9b23241a0efd3f7500318405c3518dba6b669ea10904eba266c29ab90fc722f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3907e2136f0103c819943689cceace3d4f5428bedab749d25ae8afdaf5ef74 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=99cce8f25e45b84ea11bb53afa95131a80faed0345ed3f328b830166eaed5a + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a9ea932312f389043a091fca6aea3f0dd2859c7c60729aa8c714 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466473a0058daa80d9c2e3d297344328bfcfa46eb6b8e4022a115b5 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f336d406e1f75f3ffd3865c92ce137c55e37dc49e27210e05254c2ec3ad7ee4a99bac244d3d9414db9516c6eaa31537bbf7fdff96934ac26427ec01d5f97303ba310f8b5d310f5590972 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dee33db18e140806fbdc44c4f3b2d7860948d4cc1938dae2dd41e13146756d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=284090b027f87c4dd51fe38650b3703a08b06dd9022e6d2ffc7f2b04a28459 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a47374f2616d600032043446710da74f47e21009109681b36f63 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622ec1deae64ffca2c0e9a4719b0ac129654a6acec3acfdf100a8 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=0d06059800951529977ab99abf46011735b52bc602ed118b505e013091719a0818a72afc1a92deb5ac2e19e428bc75ec462350558a18072bb0fb30156b1ea8a40a2c70af2e9bf20ad691 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0d616739d9678ba60390dfb5a27c4f636820ea559fcd84a049ce5c785cbee3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6f68ab6c0bffe6cebc38e8351dbd50541a4e645e765db0b3582db6711216e2 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625400c129b407b0e1a7e81cd0856da2332b21089505096cb0f590c5 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e5d916dabcaa33741dd98e41128d5e0f20a6a45671f3d1848c2b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=6ffc44aa06250c17e707f2496732412ed194ea271ed8d0db223b9db3cec1719cc83c5ae88e63fc64b2dfff43b873a068b95e7190573128cae00b528948bb3b6e234c1e93e9612e96e781 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1d203dde50bb9c29b43ea61990dc7f33af190af9c04ca8e2dde93314f17e83 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=78be8aa2d277eb4e3dfb5e3f8de1b46b8bf8a0369ed052fde5c5ddb35f3d1b + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254abb638c9b7f9e37475bc13b640bcd2413ef6ac24ddfc1b375856 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661b1d6ab5f61f9808b5ba36778c746d1dd4ef83c6344dab022aab +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c533dd475d8136b5aeaa4c5113f90ad850eb9f23b6b4c6101f361d28ae49237b5a205d18fc908864cac4b3687c9bab1160a25c00f34525741269fff47fe9804b1ea44f2af599eda0f6a3 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e2eac4b51925c4c1a6d132387b7e72cdb73d43a28e5a77d0792fa9741803ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=bd4e9d62222743b195d68b066ec04f67fdc2303d73abf6fbd9a2256d3a03aa + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466608b752c761dbdbff13c1cf118a78012 +msg_2_payload= +msg_2_ciphertext=3fd53af07c2c674ca7cf182726641c4c02d7c8d3b0dfecdafecf43b741fac77b5d6677b9332a441dfa111bc6567e02e3f00da36393accef162e17752f5678f96 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3907e2136f0103c819943689cceace3d4f5428bedab749d25ae8afdaf5ef74 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=99cce8f25e45b84ea11bb53afa95131a80faed0345ed3f328b830166eaed5a + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ec1ea27017f8e7707f18f51064fd2add +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466802a509fd08046ae49f47f74a4e0ccc6 +msg_2_payload= +msg_2_ciphertext=f336d406e1f75f3ffd3865c92ce137c55e37dc49e27210e05254c2ec3ad7ee4a1684c6ebf8ef1e82a68eb2b50a3099ed665dc1639b91800662be46495764ae43 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dee33db18e140806fbdc44c4f3b2d7860948d4cc1938dae2dd41e13146756d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=284090b027f87c4dd51fe38650b3703a08b06dd9022e6d2ffc7f2b04a28459 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547cab3a68cd70802365a6f31f3bd5404e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846661068b4ce2fe89e3b22be23143b20354 +msg_2_payload= +msg_2_ciphertext=0d06059800951529977ab99abf46011735b52bc602ed118b505e013091719a085ee2b4469aa934e1e0120d07cb930ba2333bdc2aebcb22fb4a1ce4237331866d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0d616739d9678ba60390dfb5a27c4f636820ea559fcd84a049ce5c785cbee3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6f68ab6c0bffe6cebc38e8351dbd50541a4e645e765db0b3582db6711216e2 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce578828a73922e9e4dffa89512bc9a2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466de48548f3293ba62560009b242fee319 +msg_2_payload= +msg_2_ciphertext=6ffc44aa06250c17e707f2496732412ed194ea271ed8d0db223b9db3cec1719c17ea0785e8debcf3099f7d5eedf069ed765e74a75a323ab224a3738a926ce4fa +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1d203dde50bb9c29b43ea61990dc7f33af190af9c04ca8e2dde93314f17e83 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=78be8aa2d277eb4e3dfb5e3f8de1b46b8bf8a0369ed052fde5c5ddb35f3d1b + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542242c47f31f968ccc897da360e62a083 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662f7cedc69bd3185e75f1b4d3809a6402 +msg_2_payload= +msg_2_ciphertext=c533dd475d8136b5aeaa4c5113f90ad850eb9f23b6b4c6101f361d28ae49237bb9f6442a7516ac401971a31b8079c7f66626d3685e14f06a107bec76b02d16a1 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e2eac4b51925c4c1a6d132387b7e72cdb73d43a28e5a77d0792fa9741803ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=bd4e9d62222743b195d68b066ec04f67fdc2303d73abf6fbd9a2256d3a03aa + +handshake=Noise_XN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846668e545d2dc0b6d33da9f921c05aa32b4aa4dd9d7b520452ff0d3 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=3fd53af07c2c674ca7cf182726641c4c02d7c8d3b0dfecdafecf43b741fac77b589759479eeb6de299615797705822d6d3f7500318405c3518db94f99a9ee65a5cbdfc4901fe80c7d645 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=3907e2136f0103c819943689cceace3d4f5428bedab749d25ae8afdaf5ef74 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=99cce8f25e45b84ea11bb53afa95131a80faed0345ed3f328b830166eaed5a + +handshake=Noise_XNpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a9ea932312f389043a0905f635244ebed0c959d850a67d2bfcdb +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466473a0058daa80d9c2e3dcab025910801eed3e0cdb0fb880d3d6b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=f336d406e1f75f3ffd3865c92ce137c55e37dc49e27210e05254c2ec3ad7ee4a368bf01b9da36e4ce6b554e8b73dab13bf7fdff96934ac26427ebbb2701fc32e0ffccb9c3bb8b0aefb75 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=dee33db18e140806fbdc44c4f3b2d7860948d4cc1938dae2dd41e13146756d +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=284090b027f87c4dd51fe38650b3703a08b06dd9022e6d2ffc7f2b04a28459 + +handshake=Noise_XNpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a47374f2616d600032047892120a00630119ec5dc6a4442dda22 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622ec1deae64ffca2c0e9c34fa5a2bbf1968c6d2c1d80fc911a28 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=0d06059800951529977ab99abf46011735b52bc602ed118b505e013091719a08f99960c571a1598776bac8555377f9d7462350558a18072bb0fbed68cd772ec5bc4899aeffa332303bfb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=0d616739d9678ba60390dfb5a27c4f636820ea559fcd84a049ce5c785cbee3 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=6f68ab6c0bffe6cebc38e8351dbd50541a4e645e765db0b3582db6711216e2 + +handshake=Noise_XNpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625400c129b407b0e1a7e81ca404bfbae707682f2c14be89ae10c1d8 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466e5d916dabcaa33741dd926fadac6a68a33856977d6b9809f174b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=6ffc44aa06250c17e707f2496732412ed194ea271ed8d0db223b9db3cec1719ce8e013412dd540377d8d28be4b70dc54b95e7190573128cae00b52f12a95c947a65121d7b922ba35ef3d +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1d203dde50bb9c29b43ea61990dc7f33af190af9c04ca8e2dde93314f17e83 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=78be8aa2d277eb4e3dfb5e3f8de1b46b8bf8a0369ed052fde5c5ddb35f3d1b + +handshake=Noise_XNpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254abb638c9b7f9e37475bc49791331a682b67199936ecb513e38c6 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484661b1d6ab5f61f9808b5bac4d0141615d581366e86cf1c7c01310b +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=c533dd475d8136b5aeaa4c5113f90ad850eb9f23b6b4c6101f361d28ae49237b7fb184f15e468b37794ce697f1bc1ec960a25c00f34525741269d02c60c542110a1f17bd4fda90a7b3bf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=e2eac4b51925c4c1a6d132387b7e72cdb73d43a28e5a77d0792fa9741803ef +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=bd4e9d62222743b195d68b066ec04f67fdc2303d73abf6fbd9a2256d3a03aa + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bf81cc58fc81923794e9cb78b175e98f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19cc2591829276b739f9f5b1deb652104dc294700bfa4bff444556a1eb66a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79d57fd9146cc45d81a557ccb290399035dee037ad22c8371fb245eea2a937 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e53b95e290bf8014fe7d452af24a73fec879b75957a17db1f438bcc24f70495334d65fed40a1f58a9a10cebb1fad680bc94b53651dc947759b6c639ef74b6de +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666fcc7926e731cd7c4fd845094bb80e47 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2355e5c0f0d55bab43293892b2560f6d625596a578d4688a84723a0e97afa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=33747bd7e8cd49233efc2b656b41a9ef65fbd5435320b83260b3ab33d71b1e + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625452bc63f42d0ef66c39248c5cfdc031cacb4c05da27eac1e2da9dc4e76a8c85c97398cb24c0e3770a64c92be982b477907c6ec27d84ab39aa5182d2a2c372cdae +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846667dfafc165b8d7c12f5b3dfdb65a3e2d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=336f4092772f3176d10c7bc03010e9b478b4cac44381de9ebe043c1ef5a46e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=06926f4dab3ecdf3d21d9e823d767be93e539cdb751c196465d0b05721229c + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541905fbbca99a3dae4a0e7dfc37f07ea4a5e4482ed7639d9c957eac004eb91b1964d790510ea069614527929196d827e38e8026e56b9e9d4fecf24dc12ee4556c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666ef6fc0cfd40f5cc18f051ab1a038f20 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=435fd3ce23b58ba31718d8851ab789a904d59c6aad42259d48a9ce3966fde9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b1703823277c5285e8d3dbb9f6d5e87b77eb8a80f12ceea78de50f0a39a6c9 + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b7f5acb19587ea6253e2dd0e216a6edd1deb1c0e132cd18977f3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19cc2591829276b739f9f5b1deb652104dc294700bfa4bff444556a1eb66a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79d57fd9146cc45d81a557ccb290399035dee037ad22c8371fb245eea2a937 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e53b95e290bf8014fe7d452af24a73fec879b75957a17db1f438bcc24f70495334d65fed40a1f58a9a10cebb1fad68014380d2bea0381c1510e67e5d0b8776c202c821ae1403340c30a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664a001ad9502defe28afd10d518c7a7c7500451e748ac3a7af324 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2355e5c0f0d55bab43293892b2560f6d625596a578d4688a84723a0e97afa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=33747bd7e8cd49233efc2b656b41a9ef65fbd5435320b83260b3ab33d71b1e + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625452bc63f42d0ef66c39248c5cfdc031cacb4c05da27eac1e2da9dc4e76a8c85c97398cb24c0e3770a64c92be982b47790eb1556d2552e1ad7246336cdd4e094fd89ddefeca031320b6331 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663554a6fc7e2cb03ff28cd7c1b199ee0b0e112ed1e01545886262 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=336f4092772f3176d10c7bc03010e9b478b4cac44381de9ebe043c1ef5a46e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=06926f4dab3ecdf3d21d9e823d767be93e539cdb751c196465d0b05721229c + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541905fbbca99a3dae4a0e7dfc37f07ea4a5e4482ed7639d9c957eac004eb91b1964d790510ea069614527929196d827e3359e9010a82b92594f4d8f37f110d89ddea2428fd23087113089 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ff02318aba77b517f05b7b59fa9e11a4838e31504dfe99625976 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=435fd3ce23b58ba31718d8851ab789a904d59c6aad42259d48a9ce3966fde9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b1703823277c5285e8d3dbb9f6d5e87b77eb8a80f12ceea78de50f0a39a6c9 + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846632e0ebbe49f1eb985aae92e521edf80e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19cc2591829276b739f9f5b1deb652104dc294700bfa4bff444556a1eb66a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79d57fd9146cc45d81a557ccb290399035dee037ad22c8371fb245eea2a937 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e53b95e290bf8014fe7d452af24a73fec879b75957a17db1f438bcc24f70495155c30fea666bba0fc0ae69c4c3892c154dcfb7b599413a962eeb3d24ad9e8e2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466276df8c1ea699ceec119c8325ba3eac3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2355e5c0f0d55bab43293892b2560f6d625596a578d4688a84723a0e97afa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=33747bd7e8cd49233efc2b656b41a9ef65fbd5435320b83260b3ab33d71b1e + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625452bc63f42d0ef66c39248c5cfdc031cacb4c05da27eac1e2da9dc4e76a8c85c90450ae312299b436e3950e316d28b5c0ad15e29ba03f6668dcde2109f6c74e97 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c12c9edb807ded3c07db4936d0c7e41e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=336f4092772f3176d10c7bc03010e9b478b4cac44381de9ebe043c1ef5a46e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=06926f4dab3ecdf3d21d9e823d767be93e539cdb751c196465d0b05721229c + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541905fbbca99a3dae4a0e7dfc37f07ea4a5e4482ed7639d9c957eac004eb91b195ce984c7b5582ba0dfcb498774dc44f5ab63c89ec6b9ac8067f9267dcc1a63f1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe750a4d7c95a9f0882b1a9c26a77542 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=435fd3ce23b58ba31718d8851ab789a904d59c6aad42259d48a9ce3966fde9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b1703823277c5285e8d3dbb9f6d5e87b77eb8a80f12ceea78de50f0a39a6c9 + +handshake=Noise_IN_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b7f5acb19587ea6253e2e4d6e53530bd10bc9560791f93b225c8 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=19cc2591829276b739f9f5b1deb652104dc294700bfa4bff444556a1eb66a8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=79d57fd9146cc45d81a557ccb290399035dee037ad22c8371fb245eea2a937 + +handshake=Noise_INpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543e53b95e290bf8014fe7d452af24a73fec879b75957a17db1f438bcc24f70495155c30fea666bba0fc0ae69c4c3892c114380d2bea0381c1510e3621bfe83997a122e8107ba562249f8f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664a001ad9502defe28afde0277a125ce29e71973a85532a8d4437 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c2355e5c0f0d55bab43293892b2560f6d625596a578d4688a84723a0e97afa +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=33747bd7e8cd49233efc2b656b41a9ef65fbd5435320b83260b3ab33d71b1e + +handshake=Noise_INpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625452bc63f42d0ef66c39248c5cfdc031cacb4c05da27eac1e2da9dc4e76a8c85c90450ae312299b436e3950e316d28b5c0eb1556d2552e1ad724636fb85f3717f9e7f063b35b54e8a07412 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663554a6fc7e2cb03ff28c38dbd0beb45568b0a1252e49dccd5410 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=336f4092772f3176d10c7bc03010e9b478b4cac44381de9ebe043c1ef5a46e +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=06926f4dab3ecdf3d21d9e823d767be93e539cdb751c196465d0b05721229c + +handshake=Noise_INpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541905fbbca99a3dae4a0e7dfc37f07ea4a5e4482ed7639d9c957eac004eb91b195ce984c7b5582ba0dfcb498774dc44f5359e9010a82b92594f4d9fa434710f0c79fda3a3b18a0c7a626f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ff02318aba77b517f05b2125921d4c162f0a05516ccd87df7a84 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=435fd3ce23b58ba31718d8851ab789a904d59c6aad42259d48a9ce3966fde9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=b1703823277c5285e8d3dbb9f6d5e87b77eb8a80f12ceea78de50f0a39a6c9 + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254a653390edbd86ba1c020a9938137fa5f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484663f75cb8ff03cce740b876919370edaa2 +msg_2_payload= +msg_2_ciphertext=2fabfb16fc114fed3616c271dbf12733184f4d2e32201ffb233a4720d451cd31e29677f21209b0009b0b1751417adb13b14852eb831d09f8061228cdce3b8dea +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15b8fdb578ed7fadbd4f6fc87fd48cd3c786ca4ac3ce3a68708ec72147b8c9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9525d9e2805470da9ec648070a03e1a5e87f0c858565adbdcf7c38d3dca90e + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254cd9f6810800376a24aff6e6e1af0db21 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466a8a4486855810a350255ae76b501d6ff +msg_2_payload= +msg_2_ciphertext=7028e105675b2294d5887e5fece5ebcad0d304fc21046b7463b3bd763f84268c46023e2baf50dd6f9adac086bada593553f9324b2c733a4f06a3eeab0424f569 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=82acd07ad6c33e3e715daa31868d729a55825b1c88d55a46a9eab5984755d6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=03d80857afae5021107843912a238783a83fa86c35a2000fa1b58b3828dd98 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c10dc3cf777958d4979adbb06f3b9de3 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668bef5c4d7ee2b435fbf3ad3aac2162fa +msg_2_payload= +msg_2_ciphertext=a77384941d395fe334060bb6480ade2cbcf4787451f6d2e8cf2c258a33e91ffae12717b78c58f43727101d020a47768034b2c8893276d463971268f0d3cda130 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=815e08cd47c188260e00166f020b2a990a8a7c31f2f6e5e64362bba39e0d8b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e13c3fd28fef752772f6a9b8c56eb26866fc1004b98f3644bbbe85829d7b48 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547848a2c529eaf0a68b9583558097b0ba +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666f94344ffb9f6d96ce88e539b7f12aa7 +msg_2_payload= +msg_2_ciphertext=0c3c7a6dc99c66a026afd6caea5b4dd660846e936276107a6f114081a82408355d8e017c861668b5d83ded9d2fad8b003fb449e8a4abc3e752f974663c1b5a69 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bbf2d5f1ea82093b94e17ba2ebaa8bed2318ba50f2449b673b41b93458c247 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=afdff82cfe53ed8c4bab4d50c197b8e23c67889a2230289e6f6fb7db7a2d56 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662545489e9d87d5dbcedc653141983ec53ac +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846613383e82ec3683f2232ca1ad16f74418 +msg_2_payload= +msg_2_ciphertext=8b7820818afedd08897101cc1e914a29767619f3e142be2673ea7ddbe042c1fa3e9dcab07b0991c815e8158f679f13e7cdd71538cd3b1e69b2360994b768dcbb +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c5dd0584674d0fd555d3ba42a4c27756e954bc3aa6dc9fd0d237fbb6479c0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ea6edad32c0e8f948cd8b94072116377acff3cab42e2de8558f89b662dfa15 + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dd159df0538d164882c09160a2ccd10fdba42242c074145b85da +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664cf8cecb0ff80106624fb53f0e47e10871a53d4fca0e13a87e57 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2fabfb16fc114fed3616c271dbf12733184f4d2e32201ffb233a4720d451cd3114f0f2256fce5a731ed038a1872211679d370b0a85ae6dbf66952ead8564d9f458001c1e8732de89a6c2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15b8fdb578ed7fadbd4f6fc87fd48cd3c786ca4ac3ce3a68708ec72147b8c9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9525d9e2805470da9ec648070a03e1a5e87f0c858565adbdcf7c38d3dca90e + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542f8e3453a219c2f379b8ba373dfe48bf5c3202ee7119c5d3c1c4 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669f1384f1028d68ed124f2f6e70a6f125ff5ed65a35ba6050e3c9 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7028e105675b2294d5887e5fece5ebcad0d304fc21046b7463b3bd763f84268ca70070170e3cc469c667dbcab5091d33fd527b0687d9dbe7a2f97c52db0cac5fed733ce2236fe4adca5e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=82acd07ad6c33e3e715daa31868d729a55825b1c88d55a46a9eab5984755d6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=03d80857afae5021107843912a238783a83fa86c35a2000fa1b58b3828dd98 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dee2c560cb410ffe557c7183216c289cc5f28c4b9884a67e1607 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d19c8f7fd48e7049046c83cdc13c43a33efa46793e06ff39a406 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a77384941d395fe334060bb6480ade2cbcf4787451f6d2e8cf2c258a33e91ffa3f37dc25d204f2a58f13726a1188e2697d93f7f672b4b6c4d43b8031cba8f8cb8ba90020fac4807a0b5a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=815e08cd47c188260e00166f020b2a990a8a7c31f2f6e5e64362bba39e0d8b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e13c3fd28fef752772f6a9b8c56eb26866fc1004b98f3644bbbe85829d7b48 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542cfbefa92d7f5e6f4b3b0ec725ab9f2caa61217f018017366e84 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ded51642e5afbb65c7319672be181c2fe9d0e1679f09b04d0567 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=0c3c7a6dc99c66a026afd6caea5b4dd660846e936276107a6f114081a8240835255ad05e56c29a0f610ad13af2654759af0102ceda60fd259afc75f6e45742b54c5f6a3fccfd7eb8780f +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bbf2d5f1ea82093b94e17ba2ebaa8bed2318ba50f2449b673b41b93458c247 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=afdff82cfe53ed8c4bab4d50c197b8e23c67889a2230289e6f6fb7db7a2d56 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d150e2ff1a6fa2da4dacf29dbeead64fd190af0015c8fb958ca2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666426ad661ac863b4d54d09062ee2be0fd87bf3025af79cae760 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8b7820818afedd08897101cc1e914a29767619f3e142be2673ea7ddbe042c1fa401508f2f0a1db803daf9b9dabc72da48d62b45f1d64ba4b228fd30c887432718cae875d3e1651cdb662 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c5dd0584674d0fd555d3ba42a4c27756e954bc3aa6dc9fd0d237fbb6479c0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ea6edad32c0e8f948cd8b94072116377acff3cab42e2de8558f89b662dfa15 + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f38769232d1dfdd5d2687e83d2e0722e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466baeeae11a657b216c68c30892d7708ca +msg_2_payload= +msg_2_ciphertext=2fabfb16fc114fed3616c271dbf12733184f4d2e32201ffb233a4720d451cd317fa53017d00d6195b1d0d2797a44f7efccfdafd47eccfcf025779b8f44a7d231 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15b8fdb578ed7fadbd4f6fc87fd48cd3c786ca4ac3ce3a68708ec72147b8c9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9525d9e2805470da9ec648070a03e1a5e87f0c858565adbdcf7c38d3dca90e + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662547f46575b56bf06e0df4be5276bd1a0c7 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665065366a41253ccb091ecff34c0979bb +msg_2_payload= +msg_2_ciphertext=7028e105675b2294d5887e5fece5ebcad0d304fc21046b7463b3bd763f84268c719a26b97ebda8d8abe1262257c00c7ff6f6066751983529bd8749ca571c8fbf +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=82acd07ad6c33e3e715daa31868d729a55825b1c88d55a46a9eab5984755d6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=03d80857afae5021107843912a238783a83fa86c35a2000fa1b58b3828dd98 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625491a6d13954cfdca1f8554bb6699a070e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484662b9b293403bc2d22af87254356ae6354 +msg_2_payload= +msg_2_ciphertext=a77384941d395fe334060bb6480ade2cbcf4787451f6d2e8cf2c258a33e91ffaa3ebf5fc392cf84011e8f30ca986e88c71f87a8b6ee1cf45cf59350de8c6c2bc +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=815e08cd47c188260e00166f020b2a990a8a7c31f2f6e5e64362bba39e0d8b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e13c3fd28fef752772f6a9b8c56eb26866fc1004b98f3644bbbe85829d7b48 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ef901c59fd43f24720cea36c3a803354 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666dbb6ee57b791434d47ca6cacfc16de8 +msg_2_payload= +msg_2_ciphertext=0c3c7a6dc99c66a026afd6caea5b4dd660846e936276107a6f114081a8240835a162ae2b6521112c8c7e1ee5e0d21aabca690cbe1cf8983e08b5ac867a436a39 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bbf2d5f1ea82093b94e17ba2ebaa8bed2318ba50f2449b673b41b93458c247 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=afdff82cfe53ed8c4bab4d50c197b8e23c67889a2230289e6f6fb7db7a2d56 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d75595f126007d31a32e936c9f50a722 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484666ef153dd2970c7fb3131dd89abc724c5 +msg_2_payload= +msg_2_ciphertext=8b7820818afedd08897101cc1e914a29767619f3e142be2673ea7ddbe042c1fa00386746b5ce8ac0e980a01f2b343db441b92b41e67266483c04995455d216e2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c5dd0584674d0fd555d3ba42a4c27756e954bc3aa6dc9fd0d237fbb6479c0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ea6edad32c0e8f948cd8b94072116377acff3cab42e2de8558f89b662dfa15 + +handshake=Noise_XK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dd159df0538d164882c0fb3ac1bb4cc6ac4e27c464f5951e809e +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484664cf8cecb0ff80106624ffd90b3f32f5bb8299f54bf3028c19ce6 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=2fabfb16fc114fed3616c271dbf12733184f4d2e32201ffb233a4720d451cd31ffd8366c726d4ef7dced16efc4444f469d370b0a85ae6dbf669562da562cd93a0b837b24b7e9570fd611 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=15b8fdb578ed7fadbd4f6fc87fd48cd3c786ca4ac3ce3a68708ec72147b8c9 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=9525d9e2805470da9ec648070a03e1a5e87f0c858565adbdcf7c38d3dca90e + +handshake=Noise_XKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542f8e3453a219c2f379b8845259d60e5064b9b764387f19e57a73 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484669f1384f1028d68ed124fee35586dd6c739118976ef139b637969 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=7028e105675b2294d5887e5fece5ebcad0d304fc21046b7463b3bd763f84268c6c24589c7b12bd43d47552ad5b599b2efd527b0687d9dbe7a2f966185b50ce95791245b2ae475cfd4e0e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=82acd07ad6c33e3e715daa31868d729a55825b1c88d55a46a9eab5984755d6 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=03d80857afae5021107843912a238783a83fa86c35a2000fa1b58b3828dd98 + +handshake=Noise_XKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254dee2c560cb410ffe557cc9abb419d3d4e715a2e71e00a177b6e2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d19c8f7fd48e7049046c3725c324e1401dfb282d5cb6dd93c6b2 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=a77384941d395fe334060bb6480ade2cbcf4787451f6d2e8cf2c258a33e91ffaea6f9945a4ff4bcd5158727fa220f9487d93f7f672b4b6c4d43bd9fc3db8793f773ca7fd9200e25ace0e +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=815e08cd47c188260e00166f020b2a990a8a7c31f2f6e5e64362bba39e0d8b +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e13c3fd28fef752772f6a9b8c56eb26866fc1004b98f3644bbbe85829d7b48 + +handshake=Noise_XKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542cfbefa92d7f5e6f4b3be913e231b431c8f7c670ce206137b712 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466ded51642e5afbb65c731ed84a8d985f37bfd26a39083898cd550 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=0c3c7a6dc99c66a026afd6caea5b4dd660846e936276107a6f114081a82408355f93a02f1599bc3ff07b5da28c8ce4c7af0102ceda60fd259afcf6b6bda42e3270e8b1eb62f1706161af +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=bbf2d5f1ea82093b94e17ba2ebaa8bed2318ba50f2449b673b41b93458c247 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=afdff82cfe53ed8c4bab4d50c197b8e23c67889a2230289e6f6fb7db7a2d56 + +handshake=Noise_XKpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d150e2ff1a6fa2da4daccb89941440200125a36b9ce7441faa58 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846666426ad661ac863b4d54145127461138fe6018095b64e3f815e8 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=8b7820818afedd08897101cc1e914a29767619f3e142be2673ea7ddbe042c1fa6274c8474632d69fe1d7e8690676e85f8d62b45f1d64ba4b228f758259e5fa9b9082e4f6ff39682d48fc +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=9c5dd0584674d0fd555d3ba42a4c27756e954bc3aa6dc9fd0d237fbb6479c0 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=ea6edad32c0e8f948cd8b94072116377acff3cab42e2de8558f89b662dfa15 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9f0dff42c86abe5677abe74f6c87301577dbc1f3ffb2213827ca694a057fdbbff7f7350265fe61102c24d7d7a7e960ba8b90a679895087c7d28b1d6703f9727 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846622bf9c6171ddd4c8f682080b03504eee +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=595694f9be48f03790f699455c84578b31d14a7baedfd736d73c53f66a5657 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=621ae446b11fda3cf08e56102dac9324dee37a4e536cdc878e8b454d98bcf2 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df1f9b7f2814e2464394f35e13e46862cb009157dc0352d710c45376c6cd254409aebd0d5d8e544c64903917c911a5d9d4bb710801ef83ed8e190bd0a6090cae +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c1340c42411f7ad45a1c59bfd7d26c73 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58a23ba181962ac5c0fafdf3c45870d1d8ba060076a80550ced748c69e6cc7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef66353b5543937ee497369867d9559a0166a817be50780a7677583341cccf + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548aac9b7e52346a4de47756a681e5a97c720eef8b7faf4d312878c47eca4a0a014ddfe09618c12aed20e55a9e01da8a86b945c4f772011cb87a1bf9cadbd0519c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b8a7518e223985d3fb21a297aaeeafb7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01b3d709f2acd4b0d95de75506da47ad980c471f2afd3a436cdc59f5605a4a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d2d77f0af04d0086e77a59b4d5a4428115f60ef95ee23a56683e35a29dcb00 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d06f15f78ad0914d9715147bb5a5004b27345a838bab4aa8bc5f144afc2cf4cca972105ba526e8c92b759e028200e766f827aa12a04ecbc0bdcd9e574e007945 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668c46d966ca4fe339f9e47fd25f68de8a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6013ea114b4c4884afb82bf029f72f924bd8a32c487a15a1cef4855ba234be +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2e7119635e41a35b7e64e0adac5483b66b1a9827895124ea07d58440b654 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9f0dff42c86abe5677abe74f6c87301577dbc1f3ffb2213827ca694a057fdbbff7f7350265fe61102c24d7d7a7e960b7316fcb3b0687be852fd2fba8969816fbfaa8b459d0b59e8a42f +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f1d8bd2b9b659695f9077e7062bb0b9e7c08fd627913be183c3 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=595694f9be48f03790f699455c84578b31d14a7baedfd736d73c53f66a5657 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=621ae446b11fda3cf08e56102dac9324dee37a4e536cdc878e8b454d98bcf2 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df1f9b7f2814e2464394f35e13e46862cb009157dc0352d710c45376c6cd254409aebd0d5d8e544c64903917c911a5d908eafc7023007a5f9bcba4a414770c8f280fedba65efe10044c1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466768fb8842b9bf487b26ed03ae92c46697145f7bd53a8fdb5b0f2 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58a23ba181962ac5c0fafdf3c45870d1d8ba060076a80550ced748c69e6cc7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef66353b5543937ee497369867d9559a0166a817be50780a7677583341cccf + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548aac9b7e52346a4de47756a681e5a97c720eef8b7faf4d312878c47eca4a0a014ddfe09618c12aed20e55a9e01da8a86e47b72ebc70cede5e0b107af9e843b201edc40459ed5ddfc7632 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b5f98fed60b91df5d962379393574db5b001d76865569f45c20e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01b3d709f2acd4b0d95de75506da47ad980c471f2afd3a436cdc59f5605a4a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d2d77f0af04d0086e77a59b4d5a4428115f60ef95ee23a56683e35a29dcb00 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d06f15f78ad0914d9715147bb5a5004b27345a838bab4aa8bc5f144afc2cf4cca972105ba526e8c92b759e028200e7666a3d77b86f9aa87dcfe685e771e38b97d3c5996368c663051641 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466168e6913e78d7a2b04b2f3d5529e73e953bafe6c7ce2b1005367 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6013ea114b4c4884afb82bf029f72f924bd8a32c487a15a1cef4855ba234be +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2e7119635e41a35b7e64e0adac5483b66b1a9827895124ea07d58440b654 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9f0dff42c86abe5677abe74f6c87301577dbc1f3ffb2213827ca694a057fdbbacac81d639bfae65c7827558f90acd27f14e182372e5bee2fa04eca3d32f09a9 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466bbaba571a4d366dfe3958808b6a298f9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=595694f9be48f03790f699455c84578b31d14a7baedfd736d73c53f66a5657 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=621ae446b11fda3cf08e56102dac9324dee37a4e536cdc878e8b454d98bcf2 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df1f9b7f2814e2464394f35e13e46862cb009157dc0352d710c45376c6cd25444c70354abe531df791866bd75aa9b66d93bd99b148497ff8dd02a120c19d03d6 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484668e13033b701c665877ce0455cb6c0ac7 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58a23ba181962ac5c0fafdf3c45870d1d8ba060076a80550ced748c69e6cc7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef66353b5543937ee497369867d9559a0166a817be50780a7677583341cccf + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548aac9b7e52346a4de47756a681e5a97c720eef8b7faf4d312878c47eca4a0a01eb23f043b5a6a476be780e530597c25629f0ce0f8d269e01315d8e15f7abab45 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846665ff976798fecbf095b0dd885e8ea88f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01b3d709f2acd4b0d95de75506da47ad980c471f2afd3a436cdc59f5605a4a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d2d77f0af04d0086e77a59b4d5a4428115f60ef95ee23a56683e35a29dcb00 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d06f15f78ad0914d9715147bb5a5004b27345a838bab4aa8bc5f144afc2cf4ccb88f9ea1ebd99e94b76e50af7eee0e59549f4f47de925ee65c9dee48f8990082 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484665db536cf97f15c6ece2431fc1c0057b4 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6013ea114b4c4884afb82bf029f72f924bd8a32c487a15a1cef4855ba234be +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2e7119635e41a35b7e64e0adac5483b66b1a9827895124ea07d58440b654 + +handshake=Noise_IK_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c9f0dff42c86abe5677abe74f6c87301577dbc1f3ffb2213827ca694a057fdbbacac81d639bfae65c7827558f90acd277316fcb3b0687be852fd7e392456bb6cbe070c749f1bd7c55fc2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484667f1d8bd2b9b659695f90e35beaf5a5f5f1e7c83aa3194a2430cd +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=595694f9be48f03790f699455c84578b31d14a7baedfd736d73c53f66a5657 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=621ae446b11fda3cf08e56102dac9324dee37a4e536cdc878e8b454d98bcf2 + +handshake=Noise_IKpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df1f9b7f2814e2464394f35e13e46862cb009157dc0352d710c45376c6cd25444c70354abe531df791866bd75aa9b66d08eafc7023007a5f9bcb8ee5cc55c0598e868acab1c02d9940cc +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466768fb8842b9bf487b26ebb07b2a3d6a12d28f27f2e833b2bf498 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=58a23ba181962ac5c0fafdf3c45870d1d8ba060076a80550ced748c69e6cc7 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=ef66353b5543937ee497369867d9559a0166a817be50780a7677583341cccf + +handshake=Noise_IKpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548aac9b7e52346a4de47756a681e5a97c720eef8b7faf4d312878c47eca4a0a01eb23f043b5a6a476be780e530597c256e47b72ebc70cede5e0b1d7616523787a70c730858ab01037164b +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466b5f98fed60b91df5d962e3be6a027433a7179f44c7a09ee68b93 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=01b3d709f2acd4b0d95de75506da47ad980c471f2afd3a436cdc59f5605a4a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=d2d77f0af04d0086e77a59b4d5a4428115f60ef95ee23a56683e35a29dcb00 + +handshake=Noise_IKpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d06f15f78ad0914d9715147bb5a5004b27345a838bab4aa8bc5f144afc2cf4ccb88f9ea1ebd99e94b76e50af7eee0e596a3d77b86f9aa87dcfe61d972bc6f34d0e93751d1260fa6bf0fe +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466168e6913e78d7a2b04b2b154c5149032d1c2584051bdcf04db1d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=6013ea114b4c4884afb82bf029f72f924bd8a32c487a15a1cef4855ba234be +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=8a2e7119635e41a35b7e64e0adac5483b66b1a9827895124ea07d58440b654 + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c7f9c130891d2fcc2454ad9808ce708c7fde0ef21e72e985c38a6ed8cdaadcd96586759f804d4fa61b89ea5b36cb9b3eb1eab4273f15b629e3508d6f11a78c6d +msg_2_payload= +msg_2_ciphertext=e42e3908de4cd096b8b86320dfe9d03127451fdbfc423fd9ef86b4659fae03c86a279a2a864a1429147865a5dba40deed136252f2229fc5c4bcd2d5ec2efbfc2 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7086fc0466ee7523680d09ff7c272e2a2817a6e2d6c4ec1c209506506e8957 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e3beadf28ea871a3be666f43eaf457d030e538eb371ba48076a7db36a9a1bf + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254637a307a63f9200c59b8a1a68ec0c19c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0b9b0b4eee99d0667e049946fdcf25326ac013cdc4b28db9729186ee6609fb9238d6aa51a6202bf8eb11457923ff8ffc6b10385eca5da0f31f1259829d93a5f +msg_2_payload= +msg_2_ciphertext=612715579e991a6981e74d1e0bfd18932aa28f66fe336867c6d3174d3c4bf4af869f42fe4ac7551684c587ac550cc4c68c3548b1ba0ca04c689acb7c8be3b7fe +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c7241ad514c2c32d238263e4d45ba84d20cbe01ff02dda02e5a77bcb058e23 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8faddc8172ce807cf234a378a2fd7524446ea3aad4864580d126a4c3852b9d + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254d34be1d87db84255cd585f5b08c19fae +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f7b3af6bee5a32d2cbc5fc98e2a038b06f0d7bd8f729fa5fc96261bd82d8e2000d07ca3e3d445871aa11fd2b6b30949fc1c8ed49bdacb1dba32a4e7390b605b +msg_2_payload= +msg_2_ciphertext=329e3f756fa718b350bc245530e8eaf1656bd2453e27eac247c6ef17a9786c2740ef1b2b23ad9b104d5dd69381c51e7cc345caf8910c716648d998cfecabd13a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7897e21dd79636f43041a385c40e411e9545fafcc7460390a0f5bca87f43d2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c10882fc0a0c8abab4d609fabccaef31ab4a243b98bd69e8da2f4f4198d12a + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548ea420fcf251ddf13312a5336a636df2 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c1668235fca77e57f6b45e06441594cc4406092be47e85a4d0f04f5dd32d98f31452429b89d4d57066ff1dd64a90b41433e30ba4faf693d4eb8ae1a44176fe83 +msg_2_payload= +msg_2_ciphertext=30aea91ba89fda848b53828e1f7945fea8d996a165f077a5500c8418765d11c565611ced43dafc735dda9c270ef928e609050f44c8fbf4eae939a52a60a2a027 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1e7459e1dc3d1df643ad73799ce1d5594ca16f7cab5e7740b0b140828fd5be +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b394b3d1392c8477446a5f29188f626d8c994794ed94abe3fc552b5aa0ad11 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625410441c3e70cb5de58ffd0e9996504e13 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6a3135623749084e7af54bdb3cbefc74483b5a11791e66803483ca71b7a1cb944867eb451bbf862d7d9ca5fb44711f5945f302feafd0a9e67925eaa3c1f1199 +msg_2_payload= +msg_2_ciphertext=27f05826a4958e7232360fc6f2d5742baa781214efa55d1adfbbe6526577bfee007f1169498002cf0af19c559cb34ebb22fbf2c5136d87142b1474343bc3ea5b +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6964e5f2c89c4cc61086163641d1b0af9ecfb4c3596726e00ad65361db462e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=cf239ff75b592d7dcf14cb9d91cc682b9f216c8b98871a9e53461f0cd027de + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c7f9c130891d2fcc2454ad9808ce708c7fde0ef21e72e985c38a6ed8cdaadcd9c0e3ed9de7ec29f5c2988dab99fc75b461f5532ce998f718c56fe4ae560e9b71afacf18e82fbda729ee6 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e42e3908de4cd096b8b86320dfe9d03127451fdbfc423fd9ef86b4659fae03c8498dfa777a39cf59d06c8cf8230f924bf6cfb3372d0d7f9f5da0a2795066e1e7f5b7bc545578661f6731 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7086fc0466ee7523680d09ff7c272e2a2817a6e2d6c4ec1c209506506e8957 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e3beadf28ea871a3be666f43eaf457d030e538eb371ba48076a7db36a9a1bf + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f53528fc2e5e3678841da8d3020d1ec9c3cde9525f1fa034d263 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0b9b0b4eee99d0667e049946fdcf25326ac013cdc4b28db9729186ee6609fb9f1f42327774c03ebe566c0d4451875ca7a5cc2fc30fc4ce18187f6191c16b819f7b7e93a783733b2483c +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=612715579e991a6981e74d1e0bfd18932aa28f66fe336867c6d3174d3c4bf4af852f4aa53299efc837c5f348c327791c370a74a98c31960c68497294ff2fadbe88a06a2dc157a6e8f4b5 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c7241ad514c2c32d238263e4d45ba84d20cbe01ff02dda02e5a77bcb058e23 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8faddc8172ce807cf234a378a2fd7524446ea3aad4864580d126a4c3852b9d + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543c0d303a380071b3f64d12c29167c26ba0e640746a6b8ba79305 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f7b3af6bee5a32d2cbc5fc98e2a038b06f0d7bd8f729fa5fc96261bd82d8e208f25674cb6b70a200d2773ed5d26726ef327de53771ebf95f72dbe4eb60a939da4c801ae9b397a739be3 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=329e3f756fa718b350bc245530e8eaf1656bd2453e27eac247c6ef17a9786c276b61061945ebca80b7a12f5ea2ee8a618aca4353c7b301862fe3e98463e63541b5b37e6d60834f1ac93a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7897e21dd79636f43041a385c40e411e9545fafcc7460390a0f5bca87f43d2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c10882fc0a0c8abab4d609fabccaef31ab4a243b98bd69e8da2f4f4198d12a + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625428c6a800c7db6b39e3450a615dd5ec514a71fef6e19fffb2ba77 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c1668235fca77e57f6b45e06441594cc4406092be47e85a4d0f04f5dd32d98f38e968429f5c0735705cb897466c6a5927df7727229d5eb23876d72e07bede789d5cbe84c97f01e06e215 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=30aea91ba89fda848b53828e1f7945fea8d996a165f077a5500c8418765d11c5db9d493f47f3c1cb8eaef381dbd62541f3f1ef96eb7fe2c084eee4325981743b32763c37cad6f075a705 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1e7459e1dc3d1df643ad73799ce1d5594ca16f7cab5e7740b0b140828fd5be +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b394b3d1392c8477446a5f29188f626d8c994794ed94abe3fc552b5aa0ad11 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544fd0dcd87f6b5d78fedd77bad2dad7505040b02a60540121bef1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6a3135623749084e7af54bdb3cbefc74483b5a11791e66803483ca71b7a1cb9f3b1428ccdd741432a5ec46572ea0fa4fe7df0a60a03a8c732ae28e216c38bd7e79d1a1bfa105f955962 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=27f05826a4958e7232360fc6f2d5742baa781214efa55d1adfbbe6526577bfee490e79236f3622a63511108ce030215cc454a891d33df307ce816ea28bd4af41a015f265e9ff7386bfce +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6964e5f2c89c4cc61086163641d1b0af9ecfb4c3596726e00ad65361db462e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=cf239ff75b592d7dcf14cb9d91cc682b9f216c8b98871a9e53461f0cd027de + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c7f9c130891d2fcc2454ad9808ce708c7fde0ef21e72e985c38a6ed8cdaadcd95d49ccad379691a89b57368d70add1bd30d7757d21b91f1b9981ac3f6cc36f79 +msg_2_payload= +msg_2_ciphertext=e42e3908de4cd096b8b86320dfe9d03127451fdbfc423fd9ef86b4659fae03c8e7b0c7c5612fc71db82f4f8ab985fab34ef5d36e101b730d9ff6de037479f032 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7086fc0466ee7523680d09ff7c272e2a2817a6e2d6c4ec1c209506506e8957 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e3beadf28ea871a3be666f43eaf457d030e538eb371ba48076a7db36a9a1bf + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541835db57f7afd1d49daa50c8dc8ba362 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0b9b0b4eee99d0667e049946fdcf25326ac013cdc4b28db9729186ee6609fb99d6f9cabe4bd5995c2bd8f0dea901e842c96b0e0d0839dba70a8308aef5f58e9 +msg_2_payload= +msg_2_ciphertext=612715579e991a6981e74d1e0bfd18932aa28f66fe336867c6d3174d3c4bf4af12bedb42b816abea75e6374d29d1b39eaf86a9610e4634e7d910e01c816c6095 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c7241ad514c2c32d238263e4d45ba84d20cbe01ff02dda02e5a77bcb058e23 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8faddc8172ce807cf234a378a2fd7524446ea3aad4864580d126a4c3852b9d + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b83f0653b90ed8bb7584c0ff87006639 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f7b3af6bee5a32d2cbc5fc98e2a038b06f0d7bd8f729fa5fc96261bd82d8e20f4488fb816701391c8df57e872539cd159761d30a1d98f0bfa7867e955354fd5 +msg_2_payload= +msg_2_ciphertext=329e3f756fa718b350bc245530e8eaf1656bd2453e27eac247c6ef17a9786c27e6df7fa01c7b0ac1513c4082a90f5d44f970035277371c0148f6df35cec05a03 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7897e21dd79636f43041a385c40e411e9545fafcc7460390a0f5bca87f43d2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c10882fc0a0c8abab4d609fabccaef31ab4a243b98bd69e8da2f4f4198d12a + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625490eb6876e3e3d7653ca69b60a1be5d08 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c1668235fca77e57f6b45e06441594cc4406092be47e85a4d0f04f5dd32d98f38b5a7e29c891e1ec1cde1853a90cdd71ca86e8c8aaa3fd5617885957703a416a +msg_2_payload= +msg_2_ciphertext=30aea91ba89fda848b53828e1f7945fea8d996a165f077a5500c8418765d11c59e79cee877ef08bef46befc971b96c29a19b56b05df43b6c83feca470821f6fd +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1e7459e1dc3d1df643ad73799ce1d5594ca16f7cab5e7740b0b140828fd5be +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b394b3d1392c8477446a5f29188f626d8c994794ed94abe3fc552b5aa0ad11 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543518fec3fe15f34315c2e73630b2c3f1 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6a3135623749084e7af54bdb3cbefc74483b5a11791e66803483ca71b7a1cb97aeeb7d0720410c02c8d66601baf98737746c6975b8e2024e175a8441ef186b2 +msg_2_payload= +msg_2_ciphertext=27f05826a4958e7232360fc6f2d5742baa781214efa55d1adfbbe6526577bfee4a8842024f9763c5020dbb90dac8e3a0fd3b44e4acf9e6e959c4f72a4549db0a +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6964e5f2c89c4cc61086163641d1b0af9ecfb4c3596726e00ad65361db462e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=cf239ff75b592d7dcf14cb9d91cc682b9f216c8b98871a9e53461f0cd027de + +handshake=Noise_XX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c7f9c130891d2fcc2454ad9808ce708c7fde0ef21e72e985c38a6ed8cdaadcd9e07ed4c7d77e83b721e41d9bb2a8b57761f5532ce998f718c56f18083ab9e2f47c3f7f545a5eabbc4ece +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=e42e3908de4cd096b8b86320dfe9d03127451fdbfc423fd9ef86b4659fae03c897f77a2af21f5ce18cde8740fe9e5912f6cfb3372d0d7f9f5da0d9be88017bb339b951c56929f77fe9d6 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7086fc0466ee7523680d09ff7c272e2a2817a6e2d6c4ec1c209506506e8957 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=e3beadf28ea871a3be666f43eaf457d030e538eb371ba48076a7db36a9a1bf + +handshake=Noise_XXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f53528fc2e5e3678841db24a2abbe656a347e2116aab72adcf37 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c0b9b0b4eee99d0667e049946fdcf25326ac013cdc4b28db9729186ee6609fb92e9751b1eacd771ac88dc4c7d4efb1c27a5cc2fc30fc4ce181878bc63aff8a4baf6b4ad054cbff26334a +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=612715579e991a6981e74d1e0bfd18932aa28f66fe336867c6d3174d3c4bf4afdf33b3790ad59aa73526df9169e40433370a74a98c31960c68493f3d69a2ca0c03be3bf415520e40ce31 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=c7241ad514c2c32d238263e4d45ba84d20cbe01ff02dda02e5a77bcb058e23 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=8faddc8172ce807cf234a378a2fd7524446ea3aad4864580d126a4c3852b9d + +handshake=Noise_XXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662543c0d303a380071b3f64db0a10b87a34e6e9a7dd07f38de42e2db +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d484660f7b3af6bee5a32d2cbc5fc98e2a038b06f0d7bd8f729fa5fc96261bd82d8e20f35ffcf131b4144444f8f4c1f2620cfaf327de53771ebf95f72dc1e5f96e3b88065ebc617fd26402c9b9 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=329e3f756fa718b350bc245530e8eaf1656bd2453e27eac247c6ef17a9786c276d69f49b2c4489657ca8d3bafa6d847b8aca4353c7b301862fe306a37fb7e182b5a52adbb6b9bb5e75f8 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=7897e21dd79636f43041a385c40e411e9545fafcc7460390a0f5bca87f43d2 +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=c10882fc0a0c8abab4d609fabccaef31ab4a243b98bd69e8da2f4f4198d12a + +handshake=Noise_XXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625428c6a800c7db6b39e3456d482f8c37e883c3ff240c77407256ac +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c1668235fca77e57f6b45e06441594cc4406092be47e85a4d0f04f5dd32d98f3093e9ada779e2aa06db725fb3f6bb18d7df7727229d5eb23876d530f89eb23a25a8e657c790f0c6a3128 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=30aea91ba89fda848b53828e1f7945fea8d996a165f077a5500c8418765d11c574f126a002bc70955d52879ea92abc5cf3f1ef96eb7fe2c084eebb273c797e0f31af83f23e200defd60c +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=1e7459e1dc3d1df643ad73799ce1d5594ca16f7cab5e7740b0b140828fd5be +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=b394b3d1392c8477446a5f29188f626d8c994794ed94abe3fc552b5aa0ad11 + +handshake=Noise_XXpsk3_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662544fd0dcd87f6b5d78feddd20bcb8ab9ed16ac202410f730729c74 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466d6a3135623749084e7af54bdb3cbefc74483b5a11791e66803483ca71b7a1cb9415f46d643edb50ac242a475f8c3b60dfe7df0a60a03a8c732ae2747ed5de74ce5ba4eca1461b96283f4 +msg_2_payload=746573745f6d73675f32 +msg_2_ciphertext=27f05826a4958e7232360fc6f2d5742baa781214efa55d1adfbbe6526577bfeec049bd84112dd940b7032911a753f227c454a891d33df307ce814db7b657f732eb230e8da83fea82aa08 +msg_3_payload=79656c6c6f777375626d6172696e65 +msg_3_ciphertext=6964e5f2c89c4cc61086163641d1b0af9ecfb4c3596726e00ad65361db462e +msg_4_payload=7375626d6172696e6579656c6c6f77 +msg_4_ciphertext=cf239ff75b592d7dcf14cb9d91cc682b9f216c8b98871a9e53461f0cd027de + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9a6ba5eae47a4d838d82ae3cd62251af0f1e6561062710eca57757b8ad283b372716c241fa1daee4dd462c761e0425e0ef756d1491dcb62a578fc7be19148b9 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d33ecf8cf6b6428cb123ddb57a17c81105eee893bed02870ba1fbe6a1fd6d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=768afdad2e41013ef4720530fcaa3d78e8ab569d26b0df12aaba81f7353512 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625445eb1ca694ab03673651916b0017d230de3ad7bec80178587a26cf011486e05c5f9d359fbc1f76fbf7ca2c8b84d9d1964814e298cb91ecd67f0240ea0b75796c +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846687c4d59dec1d3e06688dc736d0cb9008a19970e60b830d3e57e452410646cf1be3362a206b49cc56fea54f9463949d52c84bfcc53b95c30bb748d62feca70b7f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c8b4e40dfbb834b84698bd810a695f53df3e2fd87cc00f58f139a90acd8721 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0182920f0cd37284f23171456739dd8a0fa6e38eebfae65def58ce6507fcec + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df0b149f68024ee0ecf15ad91c77430ce795c414352304ac1bb084a4c0f130ba06cc6c0158963bb90e57eac11fba5916dcc9df48f406180374090384031b625a +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe09a991daffe55c5da738860a7d81bd177afbd7afe306fd613ada65429cf6c08d457bb2eaff8385941e7bc7d790d6aa94b7fddf5a53f7945849e9d60dfb258b +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=00d2de63815b9ab20f34eceb6457673528ac7ab7335ae3dd19e1c64f02617a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7cb533f4e91d2b30dd83ffb04134da913889a87bb67f0fe7eacad3a1e9e3b3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4f026b6a4f4ff262e84c007e9ab72d1759dec524c7cc49daf31c9492c7aeb0ddb9f254bb6a8fc936e688df5bce734ebd80e1dd76f5e935bed228edfa3f57c5f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846695096a7c980419c321b55005e4a475252a5d36b6ee249e905d52297d498190ce746238c4a665bac4b004d86dd8cea050e4b10fcceb9a533c7bdaa217b1b2506d +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=07cb1f697855511a505ef14bd8f64516c52a3d95c11e170f665f932f69dfe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=208dc9c1918b14a9bbcbd7ff8aac5ab2b1c0f93f6fc2067eef0f9a2226b8b9 + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9a6ba5eae47a4d838d82ae3cd62251af0f1e6561062710eca57757b8ad283b353b8d7e41e40a97fd3c64c6d7ad830398411c2332b438406f5eed2edffdbb4095be726c191c27edd8b9e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d33ecf8cf6b6428cb123ddb57a17c81105eee893bed02870ba1fbe6a1fd6d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=768afdad2e41013ef4720530fcaa3d78e8ab569d26b0df12aaba81f7353512 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625445eb1ca694ab03673651916b0017d230de3ad7bec80178587a26cf011486e05c5f9d359fbc1f76fbf7ca2c8b84d9d1962bab2967e9e5759d88986ed70a527512da1d915f8c44240076a1 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846687c4d59dec1d3e06688dc736d0cb9008a19970e60b830d3e57e452410646cf1b9b0d5180cde01a3d7c7091a2b67c0f5499a102f9755ed624fafb8acf4ddc5a604b8c4964d51b7df77e70 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c8b4e40dfbb834b84698bd810a695f53df3e2fd87cc00f58f139a90acd8721 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0182920f0cd37284f23171456739dd8a0fa6e38eebfae65def58ce6507fcec + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df0b149f68024ee0ecf15ad91c77430ce795c414352304ac1bb084a4c0f130ba06cc6c0158963bb90e57eac11fba59161bdcabdf6727d20f67112b770e7ace62894baf635ad65689a0ff +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe09a991daffe55c5da738860a7d81bd177afbd7afe306fd613ada65429cf6c0e9c1bf5439c447bfb9793fbfc2f70a8aa9d85baf1604ea68faf729344153cf0f8c58c344a669cae3415a +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=00d2de63815b9ab20f34eceb6457673528ac7ab7335ae3dd19e1c64f02617a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7cb533f4e91d2b30dd83ffb04134da913889a87bb67f0fe7eacad3a1e9e3b3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4f026b6a4f4ff262e84c007e9ab72d1759dec524c7cc49daf31c9492c7aeb0ddb9f254bb6a8fc936e688df5bce734ebf197e884f1d72ae2dc61ddb527bb6219b060996c76db675a7048 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846695096a7c980419c321b55005e4a475252a5d36b6ee249e905d52297d498190ce798ec02880c5a544226355351584c7bdd8227543b8f716af2e70de5ef4426f1bf14ac4cccfcbb295d51e +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=07cb1f697855511a505ef14bd8f64516c52a3d95c11e170f665f932f69dfe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=208dc9c1918b14a9bbcbd7ff8aac5ab2b1c0f93f6fc2067eef0f9a2226b8b9 + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9a6ba5eae47a4d838d82ae3cd62251af0f1e6561062710eca57757b8ad283b3939a848593731b3ab7151893c61d09b22dc69ee03508f3df6021d1f02a67f420 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d33ecf8cf6b6428cb123ddb57a17c81105eee893bed02870ba1fbe6a1fd6d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=768afdad2e41013ef4720530fcaa3d78e8ab569d26b0df12aaba81f7353512 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625445eb1ca694ab03673651916b0017d230de3ad7bec80178587a26cf011486e05c71f19b555215765ed472763000933b07049951734c1414b84c7ecdd163bdf8d0 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846687c4d59dec1d3e06688dc736d0cb9008a19970e60b830d3e57e452410646cf1bcc1b178351d0bb46e8e1cfc2e2ec2c925a3007eed6f1d2e8a910ce5bc0dd8873 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c8b4e40dfbb834b84698bd810a695f53df3e2fd87cc00f58f139a90acd8721 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0182920f0cd37284f23171456739dd8a0fa6e38eebfae65def58ce6507fcec + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df0b149f68024ee0ecf15ad91c77430ce795c414352304ac1bb084a4c0f130ba29eef9ca8c4fccfbbf3959cf63da6a89e144ab2cb9c3dbbfcd37434f6d7a9e19 +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe09a991daffe55c5da738860a7d81bd177afbd7afe306fd613ada65429cf6c0e1e890e1a5ef0d9557ba19f1a7e1aea1e6a071fc644a03ff3f5e127da3f15098 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=00d2de63815b9ab20f34eceb6457673528ac7ab7335ae3dd19e1c64f02617a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7cb533f4e91d2b30dd83ffb04134da913889a87bb67f0fe7eacad3a1e9e3b3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4f026b6a4f4ff262e84c007e9ab72d1759dec524c7cc49daf31c9492c7aeb0da29c805edd125123f24ff0c3a68995581266147e7092a934d6386daad38bb46e +msg_1_payload= +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846695096a7c980419c321b55005e4a475252a5d36b6ee249e905d52297d498190cea526a51e27a95def76e556a85518ad342fca05d39d1498205790f19f4a8cb060 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=07cb1f697855511a505ef14bd8f64516c52a3d95c11e170f665f932f69dfe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=208dc9c1918b14a9bbcbd7ff8aac5ab2b1c0f93f6fc2067eef0f9a2226b8b9 + +handshake=Noise_IX_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662548f40c5adb68f25624ae5b214ea767a6ec94d829d3d7b5e1ad1ba6f3e2138285f746573745f6d73675f30 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466c9a6ba5eae47a4d838d82ae3cd62251af0f1e6561062710eca57757b8ad283b30a21d13abc61b4563586358ef166f2248411c2332b438406f5ee901e916db484003c3f2fb91742430d01 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=d33ecf8cf6b6428cb123ddb57a17c81105eee893bed02870ba1fbe6a1fd6d8 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=768afdad2e41013ef4720530fcaa3d78e8ab569d26b0df12aaba81f7353512 + +handshake=Noise_IXpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625445eb1ca694ab03673651916b0017d230de3ad7bec80178587a26cf011486e05c71f19b555215765ed472763000933b072bab2967e9e5759d8898095fcf5303dd11e652a29718c9d539e2 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846687c4d59dec1d3e06688dc736d0cb9008a19970e60b830d3e57e452410646cf1b1fa414ef2cf021e372c6f36b5f22040d99a102f9755ed624fafbea2c3f10be616abb8ea5db833ee24747 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=c8b4e40dfbb834b84698bd810a695f53df3e2fd87cc00f58f139a90acd8721 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=0182920f0cd37284f23171456739dd8a0fa6e38eebfae65def58ce6507fcec + +handshake=Noise_IXpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254df0b149f68024ee0ecf15ad91c77430ce795c414352304ac1bb084a4c0f130ba29eef9ca8c4fccfbbf3959cf63da6a891bdcabdf6727d20f6711779ed5d37d6def025ef48873391e6ab0 +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d48466fe09a991daffe55c5da738860a7d81bd177afbd7afe306fd613ada65429cf6c0dd8aaade8f4a82c0b661cd30c8384de7a9d85baf1604ea68faf7a6f6436d208a84c38b3126e2aa27dc9f +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=00d2de63815b9ab20f34eceb6457673528ac7ab7335ae3dd19e1c64f02617a +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=7cb533f4e91d2b30dd83ffb04134da913889a87bb67f0fe7eacad3a1e9e3b3 + +handshake=Noise_IXpsk2_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b4f026b6a4f4ff262e84c007e9ab72d1759dec524c7cc49daf31c9492c7aeb0da29c805edd125123f24ff0c3a6899558f197e884f1d72ae2dc61acbfdea65978a80d9bc549cf41a3d82a +msg_1_payload=746573745f6d73675f31 +msg_1_ciphertext=64b101b1d0be5a8704bd078f9895001fc03e8e9f9522f188dd128d9846d4846695096a7c980419c321b55005e4a475252a5d36b6ee249e905d52297d498190cee847fe1489e3150d1a19187f638c4d11d8227543b8f716af2e7024523702533cfe92e40f47e8a0a69157 +msg_2_payload=79656c6c6f777375626d6172696e65 +msg_2_ciphertext=07cb1f697855511a505ef14bd8f64516c52a3d95c11e170f665f932f69dfe9 +msg_3_payload=7375626d6172696e6579656c6c6f77 +msg_3_ciphertext=208dc9c1918b14a9bbcbd7ff8aac5ab2b1c0f93f6fc2067eef0f9a2226b8b9 + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546ba6ae849a52fad21a8cef186539f029 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a003941c6d2ae21678d1cae7b5723e9a3ae85c4e29a451baa136ddac80778b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bf8afb4d3362b8931b247215132eed804ccad21b25f1441cfd9bc6d04c4f3d + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662542df7894ef4fa3e94ca5276eab168727b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=16d2415b0d883665ecf46e0ba404ee2044dc6b3df56b7df7c1304bcd623c0a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5df813ad71e1af04b9ec69398890d674cf813768405c26ca45e9cb5ec105c8 + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625426e4002dbe75546cc56a2909b47cdabf +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b786593ecbd2d7233981e3b00cf1bdc5b6660264160e2180126c6e8696866f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=96e589406d121007fc36dedd74e3df90bb6616475b3d4efe8590cd9f514555 + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae81c7528e1cf6662cf3c3b00e02f8bba0bdfdb1bd359c71d2a5 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a003941c6d2ae21678d1cae7b5723e9a3ae85c4e29a451baa136ddac80778b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bf8afb4d3362b8931b247215132eed804ccad21b25f1441cfd9bc6d04c4f3d + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625400b9c1c865b68c526bbb861fc8415527e725b3bbabf2f533a153 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=16d2415b0d883665ecf46e0ba404ee2044dc6b3df56b7df7c1304bcd623c0a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5df813ad71e1af04b9ec69398890d674cf813768405c26ca45e9cb5ec105c8 + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c0410bca876435926147c6c772d2fd56a305cea24df5a92b0387 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b786593ecbd2d7233981e3b00cf1bdc5b6660264160e2180126c6e8696866f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=96e589406d121007fc36dedd74e3df90bb6616475b3d4efe8590cd9f514555 + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c597be68f3073fb654b56ecbf3206468 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a003941c6d2ae21678d1cae7b5723e9a3ae85c4e29a451baa136ddac80778b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bf8afb4d3362b8931b247215132eed804ccad21b25f1441cfd9bc6d04c4f3d + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254f73370fe6616ec4bbeb7ccbb4243848b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=16d2415b0d883665ecf46e0ba404ee2044dc6b3df56b7df7c1304bcd623c0a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5df813ad71e1af04b9ec69398890d674cf813768405c26ca45e9cb5ec105c8 + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ce659aaaf6e53b6e8a81af68308411bd +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b786593ecbd2d7233981e3b00cf1bdc5b6660264160e2180126c6e8696866f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=96e589406d121007fc36dedd74e3df90bb6616475b3d4efe8590cd9f514555 + +handshake=Noise_N_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254ae81c7528e1cf6662cf390a71ae79e4927b62e8f1c66496d38c2 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a003941c6d2ae21678d1cae7b5723e9a3ae85c4e29a451baa136ddac80778b +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=bf8afb4d3362b8931b247215132eed804ccad21b25f1441cfd9bc6d04c4f3d + +handshake=Noise_Npsk0_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625400b9c1c865b68c526bbb514ef34c653a58e9eec7dc694ea16530 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=16d2415b0d883665ecf46e0ba404ee2044dc6b3df56b7df7c1304bcd623c0a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5df813ad71e1af04b9ec69398890d674cf813768405c26ca45e9cb5ec105c8 + +handshake=Noise_Npsk1_25519_ChaChaPoly_BLAKE2s +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c0410bca876435926147347ce6c3e96c11793463645346d91fe5 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=b786593ecbd2d7233981e3b00cf1bdc5b6660264160e2180126c6e8696866f +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=96e589406d121007fc36dedd74e3df90bb6616475b3d4efe8590cd9f514555 + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625429ab50aa4698f977eb619f20fa5db0c5 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a191382d64297aedea686db4812eb3415ac6a86b283fa7df9091fe8d985d11 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=006d0e38f3d94cad78e0bc2e7fc323764dd28e4e03fbbe4196bd641fa6faf5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254805170152d8a6f9ed4598a42bbfb3637 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5b53ff47dd6e5708f40d5172b280f8679e6a9147bd2ba4de1e9226079a711 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5053800ab937c3b66bf646bcc4424fd90246c6e0543d79496f4ae90c466077 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625483e428f0be402913dab92da7d61d36a0 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d94826f00577ca4eeb5b4e24221c558421b4041de30a0d9549d6d5aedd618a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0752d5018d967b25613a660c4181bc0eaae495d838bd82b7137b756ca80903 + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9404e5db0f97c582cc85908ec714e1ab58dc4d2a93b13af4017 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a191382d64297aedea686db4812eb3415ac6a86b283fa7df9091fe8d985d11 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=006d0e38f3d94cad78e0bc2e7fc323764dd28e4e03fbbe4196bd641fa6faf5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625438985084386baffdc03450537b149c888a450033abd5481a43a3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5b53ff47dd6e5708f40d5172b280f8679e6a9147bd2ba4de1e9226079a711 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5053800ab937c3b66bf646bcc4424fd90246c6e0543d79496f4ae90c466077 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c5cbbe00c4ef8b94141683ed6b916bbc89ec939994431cb3b3b8 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d94826f00577ca4eeb5b4e24221c558421b4041de30a0d9549d6d5aedd618a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0752d5018d967b25613a660c4181bc0eaae495d838bd82b7137b756ca80903 + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625403eb57d94fe18fcc9932deecd7afc348 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a191382d64297aedea686db4812eb3415ac6a86b283fa7df9091fe8d985d11 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=006d0e38f3d94cad78e0bc2e7fc323764dd28e4e03fbbe4196bd641fa6faf5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662546873f10aa744f5ec809baade7f9bb124 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5b53ff47dd6e5708f40d5172b280f8679e6a9147bd2ba4de1e9226079a711 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5053800ab937c3b66bf646bcc4424fd90246c6e0543d79496f4ae90c466077 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd1662541ce699524536e124a049f0ac3797dd8b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d94826f00577ca4eeb5b4e24221c558421b4041de30a0d9549d6d5aedd618a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0752d5018d967b25613a660c4181bc0eaae495d838bd82b7137b756ca80903 + +handshake=Noise_K_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254b9404e5db0f97c582cc8df110972e1eea4a2774b24609ba244af +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a191382d64297aedea686db4812eb3415ac6a86b283fa7df9091fe8d985d11 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=006d0e38f3d94cad78e0bc2e7fc323764dd28e4e03fbbe4196bd641fa6faf5 + +handshake=Noise_Kpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625438985084386baffdc034255c43ea3072077583dcfc973d58c3e3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=e5b53ff47dd6e5708f40d5172b280f8679e6a9147bd2ba4de1e9226079a711 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=5053800ab937c3b66bf646bcc4424fd90246c6e0543d79496f4ae90c466077 + +handshake=Noise_Kpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254c5cbbe00c4ef8b9414167a0c6551ed240bd41866f4fa78e24f01 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=d94826f00577ca4eeb5b4e24221c558421b4041de30a0d9549d6d5aedd618a +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=0752d5018d967b25613a660c4181bc0eaae495d838bd82b7137b756ca80903 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e933e249a2b9389d67db3718637dd177b70511492d1f0476ab4d5fd966c29305593cce12ffb7e757e59f61a6cf8b004cff5020d551732a789d5d654a38e1ba49 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=302ae88697158440e6875b65aa5c5b0d58c3f14ac706bdd3ed593df4ad69cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8da82f0086a25cb390515103ba49260c5d5471528042200d920979798ea8b8 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e740ec34d06c470dcef511761c3f5721297c428d33234ec9e185ac7e0273bbf47bb2b8db785e7662e22b409878754858abe462deb213910f24ad63e3bb1233c3 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a74dc1186c0173a331100c9e1a2640ea95ce9ad6d3c8579ff9275679595e23 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=adf0f9718742ec49f04cab59ff0370bb070358cbdf7973d05b688cdf050ad3 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625499e50a484c198a8e9f4d6088d46c7657b70036d4e7177346ad1bbfc541b4635bae691e6043118519cd750217f4a278cb4ef463ad8be55fa547a17e495d8eb506 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c072a15ff3c5fe832398d8ea04c5a4657edb9ad855d857089bc4322d1f1b06 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=836be31bdf36237a7bdd3fd243d64403f7060dfd569abde5cc3b11e4273cd5 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e933e249a2b9389d67db3718637dd177b70511492d1f0476ab4d5fd966c29305593cce12ffb7e757e59f61a6cf8b004c77e13ebf8bab668da83118e92ef7ef36200c950d49677914286b +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=302ae88697158440e6875b65aa5c5b0d58c3f14ac706bdd3ed593df4ad69cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8da82f0086a25cb390515103ba49260c5d5471528042200d920979798ea8b8 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e740ec34d06c470dcef511761c3f5721297c428d33234ec9e185ac7e0273bbf47bb2b8db785e7662e22b409878754858a02d92d874953c00b104ac73405c5a4396415788611a588d4cea +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a74dc1186c0173a331100c9e1a2640ea95ce9ad6d3c8579ff9275679595e23 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=adf0f9718742ec49f04cab59ff0370bb070358cbdf7973d05b688cdf050ad3 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625499e50a484c198a8e9f4d6088d46c7657b70036d4e7177346ad1bbfc541b4635bae691e6043118519cd750217f4a278cbf9fb2f5702b2af7923f51b0bdea86b1de41e1a92e49c8db1d0d7 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c072a15ff3c5fe832398d8ea04c5a4657edb9ad855d857089bc4322d1f1b06 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=836be31bdf36237a7bdd3fd243d64403f7060dfd569abde5cc3b11e4273cd5 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e933e249a2b9389d67db3718637dd177b70511492d1f0476ab4d5fd966c29305587cfc935e18d8203d1bf8063842077af6b082f7be8dcc45df8cc97a3c73aec6 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=302ae88697158440e6875b65aa5c5b0d58c3f14ac706bdd3ed593df4ad69cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8da82f0086a25cb390515103ba49260c5d5471528042200d920979798ea8b8 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e740ec34d06c470dcef511761c3f5721297c428d33234ec9e185ac7e0273bbf470d1b6e261225308b65bfbcae66da68d3ecdf4e7a3f747fe4916dd970ad935ef +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a74dc1186c0173a331100c9e1a2640ea95ce9ad6d3c8579ff9275679595e23 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=adf0f9718742ec49f04cab59ff0370bb070358cbdf7973d05b688cdf050ad3 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload= +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625499e50a484c198a8e9f4d6088d46c7657b70036d4e7177346ad1bbfc541b4635b9f5b13ed3dbfa3e43f09d1c80e6cd2d65018ebc5f7b995fc2b92d89961216c4d +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c072a15ff3c5fe832398d8ea04c5a4657edb9ad855d857089bc4322d1f1b06 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=836be31bdf36237a7bdd3fd243d64403f7060dfd569abde5cc3b11e4273cd5 + +handshake=Noise_X_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e933e249a2b9389d67db3718637dd177b70511492d1f0476ab4d5fd966c29305587cfc935e18d8203d1bf8063842077a77e13ebf8bab668da831ddabbe4f889713498154527b51f921bd +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=302ae88697158440e6875b65aa5c5b0d58c3f14ac706bdd3ed593df4ad69cf +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=8da82f0086a25cb390515103ba49260c5d5471528042200d920979798ea8b8 + +handshake=Noise_Xpsk0_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd166254e740ec34d06c470dcef511761c3f5721297c428d33234ec9e185ac7e0273bbf470d1b6e261225308b65bfbcae66da68da02d92d874953c00b1048bea5c82f7f3d4e020e34f42b266ec8a +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=a74dc1186c0173a331100c9e1a2640ea95ce9ad6d3c8579ff9275679595e23 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=adf0f9718742ec49f04cab59ff0370bb070358cbdf7973d05b688cdf050ad3 + +handshake=Noise_Xpsk1_25519_ChaChaPoly_BLAKE2s +init_static=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f +resp_static=0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20 +gen_init_ephemeral=202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f +gen_resp_ephemeral=4142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60 +prologue=6e6f74736563726574 +preshared_key=2176657279736563726574766572797365637265747665727973656372657421 +msg_0_payload=746573745f6d73675f30 +msg_0_ciphertext=358072d6365880d1aeea329adf9121383851ed21a28e3b75e965d0d2cd16625499e50a484c198a8e9f4d6088d46c7657b70036d4e7177346ad1bbfc541b4635b9f5b13ed3dbfa3e43f09d1c80e6cd2d6f9fb2f5702b2af7923f59ea23e8f1e61c7ca0bdc7ce430b3e2b4 +msg_1_payload=79656c6c6f777375626d6172696e65 +msg_1_ciphertext=c072a15ff3c5fe832398d8ea04c5a4657edb9ad855d857089bc4322d1f1b06 +msg_2_payload=7375626d6172696e6579656c6c6f77 +msg_2_ciphertext=836be31bdf36237a7bdd3fd243d64403f7060dfd569abde5cc3b11e4273cd5 + diff --git a/vendor/go.uber.org/atomic/CHANGELOG.md b/vendor/go.uber.org/atomic/CHANGELOG.md index 38f564e2b..5fe03f21b 100644 --- a/vendor/go.uber.org/atomic/CHANGELOG.md +++ b/vendor/go.uber.org/atomic/CHANGELOG.md @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.10.0] - 2022-08-11 +### Added +- Add `atomic.Float32` type for atomic operations on `float32`. +- Add `CompareAndSwap` and `Swap` methods to `atomic.String`, `atomic.Error`, + and `atomic.Value`. +- Add generic `atomic.Pointer[T]` type for atomic operations on pointers of any + type. This is present only for Go 1.18 or higher, and is a drop-in for + replacement for the standard library's `sync/atomic.Pointer` type. + +### Changed +- Deprecate `CAS` methods on all types in favor of corresponding + `CompareAndSwap` methods. + +Thanks to @eNV25 and @icpd for their contributions to this release. + +[1.10.0]: https://github.com/uber-go/atomic/compare/v1.9.0...v1.10.0 + ## [1.9.0] - 2021-07-15 ### Added - Add `Float64.Swap` to match int atomic operations. diff --git a/vendor/go.uber.org/atomic/bool.go b/vendor/go.uber.org/atomic/bool.go index 209df7bbc..dfa2085f4 100644 --- a/vendor/go.uber.org/atomic/bool.go +++ b/vendor/go.uber.org/atomic/bool.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -55,8 +55,15 @@ func (x *Bool) Store(val bool) { } // CAS is an atomic compare-and-swap for bool values. +// +// Deprecated: Use CompareAndSwap. func (x *Bool) CAS(old, new bool) (swapped bool) { - return x.v.CAS(boolToInt(old), boolToInt(new)) + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for bool values. +func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) { + return x.v.CompareAndSwap(boolToInt(old), boolToInt(new)) } // Swap atomically stores the given bool and returns the old diff --git a/vendor/go.uber.org/atomic/duration.go b/vendor/go.uber.org/atomic/duration.go index 207594f5e..6f4157445 100644 --- a/vendor/go.uber.org/atomic/duration.go +++ b/vendor/go.uber.org/atomic/duration.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -56,8 +56,15 @@ func (x *Duration) Store(val time.Duration) { } // CAS is an atomic compare-and-swap for time.Duration values. +// +// Deprecated: Use CompareAndSwap. func (x *Duration) CAS(old, new time.Duration) (swapped bool) { - return x.v.CAS(int64(old), int64(new)) + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for time.Duration values. +func (x *Duration) CompareAndSwap(old, new time.Duration) (swapped bool) { + return x.v.CompareAndSwap(int64(old), int64(new)) } // Swap atomically stores the given time.Duration and returns the old diff --git a/vendor/go.uber.org/atomic/error.go b/vendor/go.uber.org/atomic/error.go index 3be19c35e..27b23ea16 100644 --- a/vendor/go.uber.org/atomic/error.go +++ b/vendor/go.uber.org/atomic/error.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -49,3 +49,14 @@ func (x *Error) Load() error { func (x *Error) Store(val error) { x.v.Store(packError(val)) } + +// CompareAndSwap is an atomic compare-and-swap for error values. +func (x *Error) CompareAndSwap(old, new error) (swapped bool) { + return x.v.CompareAndSwap(packError(old), packError(new)) +} + +// Swap atomically stores the given error and returns the old +// value. +func (x *Error) Swap(val error) (old error) { + return unpackError(x.v.Swap(packError(val))) +} diff --git a/vendor/go.uber.org/atomic/error_ext.go b/vendor/go.uber.org/atomic/error_ext.go index ffe0be21c..d31fb633b 100644 --- a/vendor/go.uber.org/atomic/error_ext.go +++ b/vendor/go.uber.org/atomic/error_ext.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -23,7 +23,7 @@ package atomic // atomic.Value panics on nil inputs, or if the underlying type changes. // Stabilize by always storing a custom struct that we control. -//go:generate bin/gen-atomicwrapper -name=Error -type=error -wrapped=Value -pack=packError -unpack=unpackError -file=error.go +//go:generate bin/gen-atomicwrapper -name=Error -type=error -wrapped=Value -pack=packError -unpack=unpackError -compareandswap -swap -file=error.go type packedError struct{ Value error } diff --git a/vendor/go.uber.org/atomic/float32.go b/vendor/go.uber.org/atomic/float32.go new file mode 100644 index 000000000..5d535a6d2 --- /dev/null +++ b/vendor/go.uber.org/atomic/float32.go @@ -0,0 +1,77 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "math" +) + +// Float32 is an atomic type-safe wrapper for float32 values. +type Float32 struct { + _ nocmp // disallow non-atomic comparison + + v Uint32 +} + +var _zeroFloat32 float32 + +// NewFloat32 creates a new Float32. +func NewFloat32(val float32) *Float32 { + x := &Float32{} + if val != _zeroFloat32 { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped float32. +func (x *Float32) Load() float32 { + return math.Float32frombits(x.v.Load()) +} + +// Store atomically stores the passed float32. +func (x *Float32) Store(val float32) { + x.v.Store(math.Float32bits(val)) +} + +// Swap atomically stores the given float32 and returns the old +// value. +func (x *Float32) Swap(val float32) (old float32) { + return math.Float32frombits(x.v.Swap(math.Float32bits(val))) +} + +// MarshalJSON encodes the wrapped float32 into JSON. +func (x *Float32) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a float32 from JSON. +func (x *Float32) UnmarshalJSON(b []byte) error { + var v float32 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/vendor/go.uber.org/atomic/float32_ext.go b/vendor/go.uber.org/atomic/float32_ext.go new file mode 100644 index 000000000..b0cd8d9c8 --- /dev/null +++ b/vendor/go.uber.org/atomic/float32_ext.go @@ -0,0 +1,76 @@ +// Copyright (c) 2020-2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "math" + "strconv" +) + +//go:generate bin/gen-atomicwrapper -name=Float32 -type=float32 -wrapped=Uint32 -pack=math.Float32bits -unpack=math.Float32frombits -swap -json -imports math -file=float32.go + +// Add atomically adds to the wrapped float32 and returns the new value. +func (f *Float32) Add(delta float32) float32 { + for { + old := f.Load() + new := old + delta + if f.CAS(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped float32 and returns the new value. +func (f *Float32) Sub(delta float32) float32 { + return f.Add(-delta) +} + +// CAS is an atomic compare-and-swap for float32 values. +// +// Deprecated: Use CompareAndSwap +func (f *Float32) CAS(old, new float32) (swapped bool) { + return f.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for float32 values. +// +// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators +// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. +// This avoids typical CompareAndSwap loops from blocking forever, e.g., +// +// for { +// old := atom.Load() +// new = f(old) +// if atom.CompareAndSwap(old, new) { +// break +// } +// } +// +// If CompareAndSwap did not match NaN to match, then the above would loop forever. +func (f *Float32) CompareAndSwap(old, new float32) (swapped bool) { + return f.v.CompareAndSwap(math.Float32bits(old), math.Float32bits(new)) +} + +// String encodes the wrapped value as a string. +func (f *Float32) String() string { + // 'g' is the behavior for floats with %v. + return strconv.FormatFloat(float64(f.Load()), 'g', -1, 32) +} diff --git a/vendor/go.uber.org/atomic/float64.go b/vendor/go.uber.org/atomic/float64.go index 8a1367184..11d5189a5 100644 --- a/vendor/go.uber.org/atomic/float64.go +++ b/vendor/go.uber.org/atomic/float64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/go.uber.org/atomic/float64_ext.go b/vendor/go.uber.org/atomic/float64_ext.go index df36b0107..48c52b0ab 100644 --- a/vendor/go.uber.org/atomic/float64_ext.go +++ b/vendor/go.uber.org/atomic/float64_ext.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -45,21 +45,28 @@ func (f *Float64) Sub(delta float64) float64 { // CAS is an atomic compare-and-swap for float64 values. // -// Note: CAS handles NaN incorrectly. NaN != NaN using Go's inbuilt operators -// but CAS allows a stored NaN to compare equal to a passed in NaN. -// This avoids typical CAS loops from blocking forever, e.g., -// -// for { -// old := atom.Load() -// new = f(old) -// if atom.CAS(old, new) { -// break -// } -// } -// -// If CAS did not match NaN to match, then the above would loop forever. +// Deprecated: Use CompareAndSwap func (f *Float64) CAS(old, new float64) (swapped bool) { - return f.v.CAS(math.Float64bits(old), math.Float64bits(new)) + return f.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for float64 values. +// +// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators +// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. +// This avoids typical CompareAndSwap loops from blocking forever, e.g., +// +// for { +// old := atom.Load() +// new = f(old) +// if atom.CompareAndSwap(old, new) { +// break +// } +// } +// +// If CompareAndSwap did not match NaN to match, then the above would loop forever. +func (f *Float64) CompareAndSwap(old, new float64) (swapped bool) { + return f.v.CompareAndSwap(math.Float64bits(old), math.Float64bits(new)) } // String encodes the wrapped value as a string. diff --git a/vendor/go.uber.org/atomic/int32.go b/vendor/go.uber.org/atomic/int32.go index 640ea36a1..b9a68f42c 100644 --- a/vendor/go.uber.org/atomic/int32.go +++ b/vendor/go.uber.org/atomic/int32.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Int32) Dec() int32 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Int32) CAS(old, new int32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int32) CompareAndSwap(old, new int32) (swapped bool) { return atomic.CompareAndSwapInt32(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/int64.go b/vendor/go.uber.org/atomic/int64.go index 9ab66b980..78d260976 100644 --- a/vendor/go.uber.org/atomic/int64.go +++ b/vendor/go.uber.org/atomic/int64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Int64) Dec() int64 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Int64) CAS(old, new int64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int64) CompareAndSwap(old, new int64) (swapped bool) { return atomic.CompareAndSwapInt64(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/nocmp.go b/vendor/go.uber.org/atomic/nocmp.go index a8201cb4a..54b74174a 100644 --- a/vendor/go.uber.org/atomic/nocmp.go +++ b/vendor/go.uber.org/atomic/nocmp.go @@ -23,13 +23,13 @@ package atomic // nocmp is an uncomparable struct. Embed this inside another struct to make // it uncomparable. // -// type Foo struct { -// nocmp -// // ... -// } +// type Foo struct { +// nocmp +// // ... +// } // // This DOES NOT: // -// - Disallow shallow copies of structs -// - Disallow comparison of pointers to uncomparable structs +// - Disallow shallow copies of structs +// - Disallow comparison of pointers to uncomparable structs type nocmp [0]func() diff --git a/vendor/go.uber.org/atomic/pointer_go118.go b/vendor/go.uber.org/atomic/pointer_go118.go new file mode 100644 index 000000000..e0f47dba4 --- /dev/null +++ b/vendor/go.uber.org/atomic/pointer_go118.go @@ -0,0 +1,60 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.18 && !go1.19 +// +build go1.18,!go1.19 + +package atomic + +import "unsafe" + +type Pointer[T any] struct { + _ nocmp // disallow non-atomic comparison + p UnsafePointer +} + +// NewPointer creates a new Pointer. +func NewPointer[T any](v *T) *Pointer[T] { + var p Pointer[T] + if v != nil { + p.p.Store(unsafe.Pointer(v)) + } + return &p +} + +// Load atomically loads the wrapped value. +func (p *Pointer[T]) Load() *T { + return (*T)(p.p.Load()) +} + +// Store atomically stores the passed value. +func (p *Pointer[T]) Store(val *T) { + p.p.Store(unsafe.Pointer(val)) +} + +// Swap atomically swaps the wrapped pointer and returns the old value. +func (p *Pointer[T]) Swap(val *T) (old *T) { + return (*T)(p.p.Swap(unsafe.Pointer(val))) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { + return p.p.CompareAndSwap(unsafe.Pointer(old), unsafe.Pointer(new)) +} diff --git a/vendor/go.uber.org/atomic/pointer_go119.go b/vendor/go.uber.org/atomic/pointer_go119.go new file mode 100644 index 000000000..6726f17ad --- /dev/null +++ b/vendor/go.uber.org/atomic/pointer_go119.go @@ -0,0 +1,61 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.19 +// +build go1.19 + +package atomic + +import "sync/atomic" + +// Pointer is an atomic pointer of type *T. +type Pointer[T any] struct { + _ nocmp // disallow non-atomic comparison + p atomic.Pointer[T] +} + +// NewPointer creates a new Pointer. +func NewPointer[T any](v *T) *Pointer[T] { + var p Pointer[T] + if v != nil { + p.p.Store(v) + } + return &p +} + +// Load atomically loads the wrapped value. +func (p *Pointer[T]) Load() *T { + return p.p.Load() +} + +// Store atomically stores the passed value. +func (p *Pointer[T]) Store(val *T) { + p.p.Store(val) +} + +// Swap atomically swaps the wrapped pointer and returns the old value. +func (p *Pointer[T]) Swap(val *T) (old *T) { + return p.p.Swap(val) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { + return p.p.CompareAndSwap(old, new) +} diff --git a/vendor/go.uber.org/atomic/string.go b/vendor/go.uber.org/atomic/string.go index 80df93d09..c4bea70f4 100644 --- a/vendor/go.uber.org/atomic/string.go +++ b/vendor/go.uber.org/atomic/string.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -52,3 +52,14 @@ func (x *String) Load() string { func (x *String) Store(val string) { x.v.Store(val) } + +// CompareAndSwap is an atomic compare-and-swap for string values. +func (x *String) CompareAndSwap(old, new string) (swapped bool) { + return x.v.CompareAndSwap(old, new) +} + +// Swap atomically stores the given string and returns the old +// value. +func (x *String) Swap(val string) (old string) { + return x.v.Swap(val).(string) +} diff --git a/vendor/go.uber.org/atomic/string_ext.go b/vendor/go.uber.org/atomic/string_ext.go index 83d92edaf..1f63dfd5b 100644 --- a/vendor/go.uber.org/atomic/string_ext.go +++ b/vendor/go.uber.org/atomic/string_ext.go @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,7 @@ package atomic -//go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped=Value -file=string.go -// Note: No Swap as String wraps Value, which wraps the stdlib sync/atomic.Value which -// only supports Swap as of go1.17: https://github.com/golang/go/issues/39351 +//go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped=Value -compareandswap -swap -file=string.go // String returns the wrapped value. func (s *String) String() string { diff --git a/vendor/go.uber.org/atomic/time.go b/vendor/go.uber.org/atomic/time.go index 33460fc37..1660feb14 100644 --- a/vendor/go.uber.org/atomic/time.go +++ b/vendor/go.uber.org/atomic/time.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicwrapper. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/vendor/go.uber.org/atomic/uint32.go b/vendor/go.uber.org/atomic/uint32.go index 7859a9cc3..d6f04a96d 100644 --- a/vendor/go.uber.org/atomic/uint32.go +++ b/vendor/go.uber.org/atomic/uint32.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Uint32) Dec() uint32 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Uint32) CAS(old, new uint32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { return atomic.CompareAndSwapUint32(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/uint64.go b/vendor/go.uber.org/atomic/uint64.go index 2f2a7db63..2574bdd5e 100644 --- a/vendor/go.uber.org/atomic/uint64.go +++ b/vendor/go.uber.org/atomic/uint64.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Uint64) Dec() uint64 { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Uint64) CAS(old, new uint64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { return atomic.CompareAndSwapUint64(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/uintptr.go b/vendor/go.uber.org/atomic/uintptr.go index ecf7a7727..81b275a7a 100644 --- a/vendor/go.uber.org/atomic/uintptr.go +++ b/vendor/go.uber.org/atomic/uintptr.go @@ -1,6 +1,6 @@ // @generated Code generated by gen-atomicint. -// Copyright (c) 2020-2021 Uber Technologies, Inc. +// Copyright (c) 2020-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -66,7 +66,14 @@ func (i *Uintptr) Dec() uintptr { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. func (i *Uintptr) CAS(old, new uintptr) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { return atomic.CompareAndSwapUintptr(&i.v, old, new) } diff --git a/vendor/go.uber.org/atomic/unsafe_pointer.go b/vendor/go.uber.org/atomic/unsafe_pointer.go index 169f793dc..34868baf6 100644 --- a/vendor/go.uber.org/atomic/unsafe_pointer.go +++ b/vendor/go.uber.org/atomic/unsafe_pointer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2021 Uber Technologies, Inc. +// Copyright (c) 2021-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -53,6 +53,13 @@ func (p *UnsafePointer) Swap(val unsafe.Pointer) (old unsafe.Pointer) { } // CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap func (p *UnsafePointer) CAS(old, new unsafe.Pointer) (swapped bool) { + return p.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) (swapped bool) { return atomic.CompareAndSwapPointer(&p.v, old, new) } diff --git a/vendor/go.uber.org/atomic/value.go b/vendor/go.uber.org/atomic/value.go index 671f3a382..52caedb9a 100644 --- a/vendor/go.uber.org/atomic/value.go +++ b/vendor/go.uber.org/atomic/value.go @@ -25,7 +25,7 @@ import "sync/atomic" // Value shadows the type of the same name from sync/atomic // https://godoc.org/sync/atomic#Value type Value struct { - atomic.Value - _ nocmp // disallow non-atomic comparison + + atomic.Value } diff --git a/vendor/go.uber.org/zap/CHANGELOG.md b/vendor/go.uber.org/zap/CHANGELOG.md index a2c38b72c..da36c3708 100644 --- a/vendor/go.uber.org/zap/CHANGELOG.md +++ b/vendor/go.uber.org/zap/CHANGELOG.md @@ -3,6 +3,18 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 1.23.0 (24 Aug 2022) + +Enhancements: +* [#1147][]: Add a `zapcore.LevelOf` function to determine the level of a + `LevelEnabler` or `Core`. +* [#1155][]: Add `zap.Stringers` field constructor to log arrays of objects + that implement `String() string`. + +[#1147]: https://github.com/uber-go/zap/pull/1147 +[#1155]: https://github.com/uber-go/zap/pull/1155 + + ## 1.22.0 (8 Aug 2022) Enhancements: diff --git a/vendor/go.uber.org/zap/array_go118.go b/vendor/go.uber.org/zap/array_go118.go index db36ec37f..ea94f9d75 100644 --- a/vendor/go.uber.org/zap/array_go118.go +++ b/vendor/go.uber.org/zap/array_go118.go @@ -23,7 +23,11 @@ package zap -import "go.uber.org/zap/zapcore" +import ( + "fmt" + + "go.uber.org/zap/zapcore" +) // Objects constructs a field with the given key, holding a list of the // provided objects that can be marshaled by Zap. @@ -122,3 +126,31 @@ func (os objectValues[T, P]) MarshalLogArray(arr zapcore.ArrayEncoder) error { } return nil } + +// Stringers constructs a field with the given key, holding a list of the +// output provided by the value's String method +// +// Given an object that implements String on the value receiver, you +// can log a slice of those objects with Objects like so: +// +// type Request struct{ ... } +// func (a Request) String() string +// +// var requests []Request = ... +// logger.Info("sending requests", zap.Stringers("requests", requests)) +// +// Note that these objects must implement fmt.Stringer directly. +// That is, if you're trying to marshal a []Request, the String method +// must be declared on the Request type, not its pointer (*Request). +func Stringers[T fmt.Stringer](key string, values []T) Field { + return Array(key, stringers[T](values)) +} + +type stringers[T fmt.Stringer] []T + +func (os stringers[T]) MarshalLogArray(arr zapcore.ArrayEncoder) error { + for _, o := range os { + arr.AppendString(o.String()) + } + return nil +} diff --git a/vendor/go.uber.org/zap/internal/level_enabler.go b/vendor/go.uber.org/zap/internal/level_enabler.go new file mode 100644 index 000000000..5f3e3f1b9 --- /dev/null +++ b/vendor/go.uber.org/zap/internal/level_enabler.go @@ -0,0 +1,35 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package internal + +import "go.uber.org/zap/zapcore" + +// LeveledEnabler is an interface satisfied by LevelEnablers that are able to +// report their own level. +// +// This interface is defined to use more conveniently in tests and non-zapcore +// packages. +// This cannot be imported from zapcore because of the cyclic dependency. +type LeveledEnabler interface { + zapcore.LevelEnabler + + Level() zapcore.Level +} diff --git a/vendor/go.uber.org/zap/level.go b/vendor/go.uber.org/zap/level.go index 8f86c430f..db951e19a 100644 --- a/vendor/go.uber.org/zap/level.go +++ b/vendor/go.uber.org/zap/level.go @@ -22,6 +22,7 @@ package zap import ( "go.uber.org/atomic" + "go.uber.org/zap/internal" "go.uber.org/zap/zapcore" ) @@ -70,6 +71,8 @@ type AtomicLevel struct { l *atomic.Int32 } +var _ internal.LeveledEnabler = AtomicLevel{} + // NewAtomicLevel creates an AtomicLevel with InfoLevel and above logging // enabled. func NewAtomicLevel() AtomicLevel { diff --git a/vendor/go.uber.org/zap/writer.go b/vendor/go.uber.org/zap/writer.go index 00eba4ed7..2c3dbd425 100644 --- a/vendor/go.uber.org/zap/writer.go +++ b/vendor/go.uber.org/zap/writer.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2016-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -70,7 +70,7 @@ func open(paths []string) ([]zapcore.WriteSyncer, func(), error) { for _, path := range paths { sink, err := newSink(path) if err != nil { - openErr = multierr.Append(openErr, fmt.Errorf("couldn't open sink %q: %v", path, err)) + openErr = multierr.Append(openErr, fmt.Errorf("open sink %q: %w", path, err)) continue } writers = append(writers, sink) diff --git a/vendor/go.uber.org/zap/zapcore/core.go b/vendor/go.uber.org/zap/zapcore/core.go index a1ef8b034..9dfd64051 100644 --- a/vendor/go.uber.org/zap/zapcore/core.go +++ b/vendor/go.uber.org/zap/zapcore/core.go @@ -69,6 +69,15 @@ type ioCore struct { out WriteSyncer } +var ( + _ Core = (*ioCore)(nil) + _ leveledEnabler = (*ioCore)(nil) +) + +func (c *ioCore) Level() Level { + return LevelOf(c.LevelEnabler) +} + func (c *ioCore) With(fields []Field) Core { clone := c.clone() addFields(clone.enc, fields) diff --git a/vendor/go.uber.org/zap/zapcore/hook.go b/vendor/go.uber.org/zap/zapcore/hook.go index 5db4afb30..198def991 100644 --- a/vendor/go.uber.org/zap/zapcore/hook.go +++ b/vendor/go.uber.org/zap/zapcore/hook.go @@ -27,6 +27,11 @@ type hooked struct { funcs []func(Entry) error } +var ( + _ Core = (*hooked)(nil) + _ leveledEnabler = (*hooked)(nil) +) + // RegisterHooks wraps a Core and runs a collection of user-defined callback // hooks each time a message is logged. Execution of the callbacks is blocking. // @@ -40,6 +45,10 @@ func RegisterHooks(core Core, hooks ...func(Entry) error) Core { } } +func (h *hooked) Level() Level { + return LevelOf(h.Core) +} + func (h *hooked) Check(ent Entry, ce *CheckedEntry) *CheckedEntry { // Let the wrapped Core decide whether to log this message or not. This // also gives the downstream a chance to register itself directly with the diff --git a/vendor/go.uber.org/zap/zapcore/increase_level.go b/vendor/go.uber.org/zap/zapcore/increase_level.go index 5a1749261..7a11237ae 100644 --- a/vendor/go.uber.org/zap/zapcore/increase_level.go +++ b/vendor/go.uber.org/zap/zapcore/increase_level.go @@ -27,6 +27,11 @@ type levelFilterCore struct { level LevelEnabler } +var ( + _ Core = (*levelFilterCore)(nil) + _ leveledEnabler = (*levelFilterCore)(nil) +) + // NewIncreaseLevelCore creates a core that can be used to increase the level of // an existing Core. It cannot be used to decrease the logging level, as it acts // as a filter before calling the underlying core. If level decreases the log level, @@ -45,6 +50,10 @@ func (c *levelFilterCore) Enabled(lvl Level) bool { return c.level.Enabled(lvl) } +func (c *levelFilterCore) Level() Level { + return LevelOf(c.level) +} + func (c *levelFilterCore) With(fields []Field) Core { return &levelFilterCore{c.core.With(fields), c.level} } diff --git a/vendor/go.uber.org/zap/zapcore/level.go b/vendor/go.uber.org/zap/zapcore/level.go index 56e88dc0c..e01a24131 100644 --- a/vendor/go.uber.org/zap/zapcore/level.go +++ b/vendor/go.uber.org/zap/zapcore/level.go @@ -53,6 +53,11 @@ const ( _minLevel = DebugLevel _maxLevel = FatalLevel + + // InvalidLevel is an invalid value for Level. + // + // Core implementations may panic if they see messages of this level. + InvalidLevel = _maxLevel + 1 ) // ParseLevel parses a level based on the lower-case or all-caps ASCII @@ -67,6 +72,43 @@ func ParseLevel(text string) (Level, error) { return level, err } +type leveledEnabler interface { + LevelEnabler + + Level() Level +} + +// LevelOf reports the minimum enabled log level for the given LevelEnabler +// from Zap's supported log levels, or [InvalidLevel] if none of them are +// enabled. +// +// A LevelEnabler may implement a 'Level() Level' method to override the +// behavior of this function. +// +// func (c *core) Level() Level { +// return c.currentLevel +// } +// +// It is recommended that [Core] implementations that wrap other cores use +// LevelOf to retrieve the level of the wrapped core. For example, +// +// func (c *coreWrapper) Level() Level { +// return zapcore.LevelOf(c.wrappedCore) +// } +func LevelOf(enab LevelEnabler) Level { + if lvler, ok := enab.(leveledEnabler); ok { + return lvler.Level() + } + + for lvl := _minLevel; lvl <= _maxLevel; lvl++ { + if enab.Enabled(lvl) { + return lvl + } + } + + return InvalidLevel +} + // String returns a lower-case ASCII representation of the log level. func (l Level) String() string { switch l { diff --git a/vendor/go.uber.org/zap/zapcore/sampler.go b/vendor/go.uber.org/zap/zapcore/sampler.go index a15b7c910..dc518055a 100644 --- a/vendor/go.uber.org/zap/zapcore/sampler.go +++ b/vendor/go.uber.org/zap/zapcore/sampler.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2016-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -175,6 +175,11 @@ type sampler struct { hook func(Entry, SamplingDecision) } +var ( + _ Core = (*sampler)(nil) + _ leveledEnabler = (*sampler)(nil) +) + // NewSampler creates a Core that samples incoming entries, which // caps the CPU and I/O load of logging while attempting to preserve a // representative subset of your logs. @@ -192,6 +197,10 @@ func NewSampler(core Core, tick time.Duration, first, thereafter int) Core { return NewSamplerWithOptions(core, tick, first, thereafter) } +func (s *sampler) Level() Level { + return LevelOf(s.Core) +} + func (s *sampler) With(fields []Field) Core { return &sampler{ Core: s.Core.With(fields), diff --git a/vendor/go.uber.org/zap/zapcore/tee.go b/vendor/go.uber.org/zap/zapcore/tee.go index 07a32eef9..9bb32f055 100644 --- a/vendor/go.uber.org/zap/zapcore/tee.go +++ b/vendor/go.uber.org/zap/zapcore/tee.go @@ -1,4 +1,4 @@ -// Copyright (c) 2016 Uber Technologies, Inc. +// Copyright (c) 2016-2022 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -24,6 +24,11 @@ import "go.uber.org/multierr" type multiCore []Core +var ( + _ leveledEnabler = multiCore(nil) + _ Core = multiCore(nil) +) + // NewTee creates a Core that duplicates log entries into two or more // underlying Cores. // @@ -48,6 +53,16 @@ func (mc multiCore) With(fields []Field) Core { return clone } +func (mc multiCore) Level() Level { + minLvl := _maxLevel // mc is never empty + for i := range mc { + if lvl := LevelOf(mc[i]); lvl < minLvl { + minLvl = lvl + } + } + return minLvl +} + func (mc multiCore) Enabled(lvl Level) bool { for i := range mc { if mc[i].Enabled(lvl) { diff --git a/vendor/github.com/marten-seemann/qtls-go1-16/LICENSE b/vendor/golang.org/x/exp/LICENSE similarity index 100% rename from vendor/github.com/marten-seemann/qtls-go1-16/LICENSE rename to vendor/golang.org/x/exp/LICENSE diff --git a/vendor/golang.org/x/exp/PATENTS b/vendor/golang.org/x/exp/PATENTS new file mode 100644 index 000000000..733099041 --- /dev/null +++ b/vendor/golang.org/x/exp/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/vendor/golang.org/x/exp/constraints/constraints.go b/vendor/golang.org/x/exp/constraints/constraints.go new file mode 100644 index 000000000..2c033dff4 --- /dev/null +++ b/vendor/golang.org/x/exp/constraints/constraints.go @@ -0,0 +1,50 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package constraints defines a set of useful constraints to be used +// with type parameters. +package constraints + +// Signed is a constraint that permits any signed integer type. +// If future releases of Go add new predeclared signed integer types, +// this constraint will be modified to include them. +type Signed interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 +} + +// Unsigned is a constraint that permits any unsigned integer type. +// If future releases of Go add new predeclared unsigned integer types, +// this constraint will be modified to include them. +type Unsigned interface { + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr +} + +// Integer is a constraint that permits any integer type. +// If future releases of Go add new predeclared integer types, +// this constraint will be modified to include them. +type Integer interface { + Signed | Unsigned +} + +// Float is a constraint that permits any floating-point type. +// If future releases of Go add new predeclared floating-point types, +// this constraint will be modified to include them. +type Float interface { + ~float32 | ~float64 +} + +// Complex is a constraint that permits any complex numeric type. +// If future releases of Go add new predeclared complex numeric types, +// this constraint will be modified to include them. +type Complex interface { + ~complex64 | ~complex128 +} + +// Ordered is a constraint that permits any ordered type: any type +// that supports the operators < <= >= >. +// If future releases of Go add new ordered types, +// this constraint will be modified to include them. +type Ordered interface { + Integer | Float | ~string +} diff --git a/vendor/golang.org/x/mod/modfile/print.go b/vendor/golang.org/x/mod/modfile/print.go new file mode 100644 index 000000000..524f93022 --- /dev/null +++ b/vendor/golang.org/x/mod/modfile/print.go @@ -0,0 +1,174 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Module file printer. + +package modfile + +import ( + "bytes" + "fmt" + "strings" +) + +// Format returns a go.mod file as a byte slice, formatted in standard style. +func Format(f *FileSyntax) []byte { + pr := &printer{} + pr.file(f) + return pr.Bytes() +} + +// A printer collects the state during printing of a file or expression. +type printer struct { + bytes.Buffer // output buffer + comment []Comment // pending end-of-line comments + margin int // left margin (indent), a number of tabs +} + +// printf prints to the buffer. +func (p *printer) printf(format string, args ...interface{}) { + fmt.Fprintf(p, format, args...) +} + +// indent returns the position on the current line, in bytes, 0-indexed. +func (p *printer) indent() int { + b := p.Bytes() + n := 0 + for n < len(b) && b[len(b)-1-n] != '\n' { + n++ + } + return n +} + +// newline ends the current line, flushing end-of-line comments. +func (p *printer) newline() { + if len(p.comment) > 0 { + p.printf(" ") + for i, com := range p.comment { + if i > 0 { + p.trim() + p.printf("\n") + for i := 0; i < p.margin; i++ { + p.printf("\t") + } + } + p.printf("%s", strings.TrimSpace(com.Token)) + } + p.comment = p.comment[:0] + } + + p.trim() + p.printf("\n") + for i := 0; i < p.margin; i++ { + p.printf("\t") + } +} + +// trim removes trailing spaces and tabs from the current line. +func (p *printer) trim() { + // Remove trailing spaces and tabs from line we're about to end. + b := p.Bytes() + n := len(b) + for n > 0 && (b[n-1] == '\t' || b[n-1] == ' ') { + n-- + } + p.Truncate(n) +} + +// file formats the given file into the print buffer. +func (p *printer) file(f *FileSyntax) { + for _, com := range f.Before { + p.printf("%s", strings.TrimSpace(com.Token)) + p.newline() + } + + for i, stmt := range f.Stmt { + switch x := stmt.(type) { + case *CommentBlock: + // comments already handled + p.expr(x) + + default: + p.expr(x) + p.newline() + } + + for _, com := range stmt.Comment().After { + p.printf("%s", strings.TrimSpace(com.Token)) + p.newline() + } + + if i+1 < len(f.Stmt) { + p.newline() + } + } +} + +func (p *printer) expr(x Expr) { + // Emit line-comments preceding this expression. + if before := x.Comment().Before; len(before) > 0 { + // Want to print a line comment. + // Line comments must be at the current margin. + p.trim() + if p.indent() > 0 { + // There's other text on the line. Start a new line. + p.printf("\n") + } + // Re-indent to margin. + for i := 0; i < p.margin; i++ { + p.printf("\t") + } + for _, com := range before { + p.printf("%s", strings.TrimSpace(com.Token)) + p.newline() + } + } + + switch x := x.(type) { + default: + panic(fmt.Errorf("printer: unexpected type %T", x)) + + case *CommentBlock: + // done + + case *LParen: + p.printf("(") + case *RParen: + p.printf(")") + + case *Line: + p.tokens(x.Token) + + case *LineBlock: + p.tokens(x.Token) + p.printf(" ") + p.expr(&x.LParen) + p.margin++ + for _, l := range x.Line { + p.newline() + p.expr(l) + } + p.margin-- + p.newline() + p.expr(&x.RParen) + } + + // Queue end-of-line comments for printing when we + // reach the end of the line. + p.comment = append(p.comment, x.Comment().Suffix...) +} + +func (p *printer) tokens(tokens []string) { + sep := "" + for _, t := range tokens { + if t == "," || t == ")" || t == "]" || t == "}" { + sep = "" + } + p.printf("%s%s", sep, t) + sep = " " + if t == "(" || t == "[" || t == "{" { + sep = "" + } + } +} diff --git a/vendor/golang.org/x/mod/modfile/read.go b/vendor/golang.org/x/mod/modfile/read.go new file mode 100644 index 000000000..70947ee77 --- /dev/null +++ b/vendor/golang.org/x/mod/modfile/read.go @@ -0,0 +1,958 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modfile + +import ( + "bytes" + "errors" + "fmt" + "os" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// A Position describes an arbitrary source position in a file, including the +// file, line, column, and byte offset. +type Position struct { + Line int // line in input (starting at 1) + LineRune int // rune in line (starting at 1) + Byte int // byte in input (starting at 0) +} + +// add returns the position at the end of s, assuming it starts at p. +func (p Position) add(s string) Position { + p.Byte += len(s) + if n := strings.Count(s, "\n"); n > 0 { + p.Line += n + s = s[strings.LastIndex(s, "\n")+1:] + p.LineRune = 1 + } + p.LineRune += utf8.RuneCountInString(s) + return p +} + +// An Expr represents an input element. +type Expr interface { + // Span returns the start and end position of the expression, + // excluding leading or trailing comments. + Span() (start, end Position) + + // Comment returns the comments attached to the expression. + // This method would normally be named 'Comments' but that + // would interfere with embedding a type of the same name. + Comment() *Comments +} + +// A Comment represents a single // comment. +type Comment struct { + Start Position + Token string // without trailing newline + Suffix bool // an end of line (not whole line) comment +} + +// Comments collects the comments associated with an expression. +type Comments struct { + Before []Comment // whole-line comments before this expression + Suffix []Comment // end-of-line comments after this expression + + // For top-level expressions only, After lists whole-line + // comments following the expression. + After []Comment +} + +// Comment returns the receiver. This isn't useful by itself, but +// a Comments struct is embedded into all the expression +// implementation types, and this gives each of those a Comment +// method to satisfy the Expr interface. +func (c *Comments) Comment() *Comments { + return c +} + +// A FileSyntax represents an entire go.mod file. +type FileSyntax struct { + Name string // file path + Comments + Stmt []Expr +} + +func (x *FileSyntax) Span() (start, end Position) { + if len(x.Stmt) == 0 { + return + } + start, _ = x.Stmt[0].Span() + _, end = x.Stmt[len(x.Stmt)-1].Span() + return start, end +} + +// addLine adds a line containing the given tokens to the file. +// +// If the first token of the hint matches the first token of the +// line, the new line is added at the end of the block containing hint, +// extracting hint into a new block if it is not yet in one. +// +// If the hint is non-nil buts its first token does not match, +// the new line is added after the block containing hint +// (or hint itself, if not in a block). +// +// If no hint is provided, addLine appends the line to the end of +// the last block with a matching first token, +// or to the end of the file if no such block exists. +func (x *FileSyntax) addLine(hint Expr, tokens ...string) *Line { + if hint == nil { + // If no hint given, add to the last statement of the given type. + Loop: + for i := len(x.Stmt) - 1; i >= 0; i-- { + stmt := x.Stmt[i] + switch stmt := stmt.(type) { + case *Line: + if stmt.Token != nil && stmt.Token[0] == tokens[0] { + hint = stmt + break Loop + } + case *LineBlock: + if stmt.Token[0] == tokens[0] { + hint = stmt + break Loop + } + } + } + } + + newLineAfter := func(i int) *Line { + new := &Line{Token: tokens} + if i == len(x.Stmt) { + x.Stmt = append(x.Stmt, new) + } else { + x.Stmt = append(x.Stmt, nil) + copy(x.Stmt[i+2:], x.Stmt[i+1:]) + x.Stmt[i+1] = new + } + return new + } + + if hint != nil { + for i, stmt := range x.Stmt { + switch stmt := stmt.(type) { + case *Line: + if stmt == hint { + if stmt.Token == nil || stmt.Token[0] != tokens[0] { + return newLineAfter(i) + } + + // Convert line to line block. + stmt.InBlock = true + block := &LineBlock{Token: stmt.Token[:1], Line: []*Line{stmt}} + stmt.Token = stmt.Token[1:] + x.Stmt[i] = block + new := &Line{Token: tokens[1:], InBlock: true} + block.Line = append(block.Line, new) + return new + } + + case *LineBlock: + if stmt == hint { + if stmt.Token[0] != tokens[0] { + return newLineAfter(i) + } + + new := &Line{Token: tokens[1:], InBlock: true} + stmt.Line = append(stmt.Line, new) + return new + } + + for j, line := range stmt.Line { + if line == hint { + if stmt.Token[0] != tokens[0] { + return newLineAfter(i) + } + + // Add new line after hint within the block. + stmt.Line = append(stmt.Line, nil) + copy(stmt.Line[j+2:], stmt.Line[j+1:]) + new := &Line{Token: tokens[1:], InBlock: true} + stmt.Line[j+1] = new + return new + } + } + } + } + } + + new := &Line{Token: tokens} + x.Stmt = append(x.Stmt, new) + return new +} + +func (x *FileSyntax) updateLine(line *Line, tokens ...string) { + if line.InBlock { + tokens = tokens[1:] + } + line.Token = tokens +} + +// markRemoved modifies line so that it (and its end-of-line comment, if any) +// will be dropped by (*FileSyntax).Cleanup. +func (line *Line) markRemoved() { + line.Token = nil + line.Comments.Suffix = nil +} + +// Cleanup cleans up the file syntax x after any edit operations. +// To avoid quadratic behavior, (*Line).markRemoved marks the line as dead +// by setting line.Token = nil but does not remove it from the slice +// in which it appears. After edits have all been indicated, +// calling Cleanup cleans out the dead lines. +func (x *FileSyntax) Cleanup() { + w := 0 + for _, stmt := range x.Stmt { + switch stmt := stmt.(type) { + case *Line: + if stmt.Token == nil { + continue + } + case *LineBlock: + ww := 0 + for _, line := range stmt.Line { + if line.Token != nil { + stmt.Line[ww] = line + ww++ + } + } + if ww == 0 { + continue + } + if ww == 1 { + // Collapse block into single line. + line := &Line{ + Comments: Comments{ + Before: commentsAdd(stmt.Before, stmt.Line[0].Before), + Suffix: commentsAdd(stmt.Line[0].Suffix, stmt.Suffix), + After: commentsAdd(stmt.Line[0].After, stmt.After), + }, + Token: stringsAdd(stmt.Token, stmt.Line[0].Token), + } + x.Stmt[w] = line + w++ + continue + } + stmt.Line = stmt.Line[:ww] + } + x.Stmt[w] = stmt + w++ + } + x.Stmt = x.Stmt[:w] +} + +func commentsAdd(x, y []Comment) []Comment { + return append(x[:len(x):len(x)], y...) +} + +func stringsAdd(x, y []string) []string { + return append(x[:len(x):len(x)], y...) +} + +// A CommentBlock represents a top-level block of comments separate +// from any rule. +type CommentBlock struct { + Comments + Start Position +} + +func (x *CommentBlock) Span() (start, end Position) { + return x.Start, x.Start +} + +// A Line is a single line of tokens. +type Line struct { + Comments + Start Position + Token []string + InBlock bool + End Position +} + +func (x *Line) Span() (start, end Position) { + return x.Start, x.End +} + +// A LineBlock is a factored block of lines, like +// +// require ( +// "x" +// "y" +// ) +type LineBlock struct { + Comments + Start Position + LParen LParen + Token []string + Line []*Line + RParen RParen +} + +func (x *LineBlock) Span() (start, end Position) { + return x.Start, x.RParen.Pos.add(")") +} + +// An LParen represents the beginning of a parenthesized line block. +// It is a place to store suffix comments. +type LParen struct { + Comments + Pos Position +} + +func (x *LParen) Span() (start, end Position) { + return x.Pos, x.Pos.add(")") +} + +// An RParen represents the end of a parenthesized line block. +// It is a place to store whole-line (before) comments. +type RParen struct { + Comments + Pos Position +} + +func (x *RParen) Span() (start, end Position) { + return x.Pos, x.Pos.add(")") +} + +// An input represents a single input file being parsed. +type input struct { + // Lexing state. + filename string // name of input file, for errors + complete []byte // entire input + remaining []byte // remaining input + tokenStart []byte // token being scanned to end of input + token token // next token to be returned by lex, peek + pos Position // current input position + comments []Comment // accumulated comments + + // Parser state. + file *FileSyntax // returned top-level syntax tree + parseErrors ErrorList // errors encountered during parsing + + // Comment assignment state. + pre []Expr // all expressions, in preorder traversal + post []Expr // all expressions, in postorder traversal +} + +func newInput(filename string, data []byte) *input { + return &input{ + filename: filename, + complete: data, + remaining: data, + pos: Position{Line: 1, LineRune: 1, Byte: 0}, + } +} + +// parse parses the input file. +func parse(file string, data []byte) (f *FileSyntax, err error) { + // The parser panics for both routine errors like syntax errors + // and for programmer bugs like array index errors. + // Turn both into error returns. Catching bug panics is + // especially important when processing many files. + in := newInput(file, data) + defer func() { + if e := recover(); e != nil && e != &in.parseErrors { + in.parseErrors = append(in.parseErrors, Error{ + Filename: in.filename, + Pos: in.pos, + Err: fmt.Errorf("internal error: %v", e), + }) + } + if err == nil && len(in.parseErrors) > 0 { + err = in.parseErrors + } + }() + + // Prime the lexer by reading in the first token. It will be available + // in the next peek() or lex() call. + in.readToken() + + // Invoke the parser. + in.parseFile() + if len(in.parseErrors) > 0 { + return nil, in.parseErrors + } + in.file.Name = in.filename + + // Assign comments to nearby syntax. + in.assignComments() + + return in.file, nil +} + +// Error is called to report an error. +// Error does not return: it panics. +func (in *input) Error(s string) { + in.parseErrors = append(in.parseErrors, Error{ + Filename: in.filename, + Pos: in.pos, + Err: errors.New(s), + }) + panic(&in.parseErrors) +} + +// eof reports whether the input has reached end of file. +func (in *input) eof() bool { + return len(in.remaining) == 0 +} + +// peekRune returns the next rune in the input without consuming it. +func (in *input) peekRune() int { + if len(in.remaining) == 0 { + return 0 + } + r, _ := utf8.DecodeRune(in.remaining) + return int(r) +} + +// peekPrefix reports whether the remaining input begins with the given prefix. +func (in *input) peekPrefix(prefix string) bool { + // This is like bytes.HasPrefix(in.remaining, []byte(prefix)) + // but without the allocation of the []byte copy of prefix. + for i := 0; i < len(prefix); i++ { + if i >= len(in.remaining) || in.remaining[i] != prefix[i] { + return false + } + } + return true +} + +// readRune consumes and returns the next rune in the input. +func (in *input) readRune() int { + if len(in.remaining) == 0 { + in.Error("internal lexer error: readRune at EOF") + } + r, size := utf8.DecodeRune(in.remaining) + in.remaining = in.remaining[size:] + if r == '\n' { + in.pos.Line++ + in.pos.LineRune = 1 + } else { + in.pos.LineRune++ + } + in.pos.Byte += size + return int(r) +} + +type token struct { + kind tokenKind + pos Position + endPos Position + text string +} + +type tokenKind int + +const ( + _EOF tokenKind = -(iota + 1) + _EOLCOMMENT + _IDENT + _STRING + _COMMENT + + // newlines and punctuation tokens are allowed as ASCII codes. +) + +func (k tokenKind) isComment() bool { + return k == _COMMENT || k == _EOLCOMMENT +} + +// isEOL returns whether a token terminates a line. +func (k tokenKind) isEOL() bool { + return k == _EOF || k == _EOLCOMMENT || k == '\n' +} + +// startToken marks the beginning of the next input token. +// It must be followed by a call to endToken, once the token's text has +// been consumed using readRune. +func (in *input) startToken() { + in.tokenStart = in.remaining + in.token.text = "" + in.token.pos = in.pos +} + +// endToken marks the end of an input token. +// It records the actual token string in tok.text. +// A single trailing newline (LF or CRLF) will be removed from comment tokens. +func (in *input) endToken(kind tokenKind) { + in.token.kind = kind + text := string(in.tokenStart[:len(in.tokenStart)-len(in.remaining)]) + if kind.isComment() { + if strings.HasSuffix(text, "\r\n") { + text = text[:len(text)-2] + } else { + text = strings.TrimSuffix(text, "\n") + } + } + in.token.text = text + in.token.endPos = in.pos +} + +// peek returns the kind of the the next token returned by lex. +func (in *input) peek() tokenKind { + return in.token.kind +} + +// lex is called from the parser to obtain the next input token. +func (in *input) lex() token { + tok := in.token + in.readToken() + return tok +} + +// readToken lexes the next token from the text and stores it in in.token. +func (in *input) readToken() { + // Skip past spaces, stopping at non-space or EOF. + for !in.eof() { + c := in.peekRune() + if c == ' ' || c == '\t' || c == '\r' { + in.readRune() + continue + } + + // Comment runs to end of line. + if in.peekPrefix("//") { + in.startToken() + + // Is this comment the only thing on its line? + // Find the last \n before this // and see if it's all + // spaces from there to here. + i := bytes.LastIndex(in.complete[:in.pos.Byte], []byte("\n")) + suffix := len(bytes.TrimSpace(in.complete[i+1:in.pos.Byte])) > 0 + in.readRune() + in.readRune() + + // Consume comment. + for len(in.remaining) > 0 && in.readRune() != '\n' { + } + + // If we are at top level (not in a statement), hand the comment to + // the parser as a _COMMENT token. The grammar is written + // to handle top-level comments itself. + if !suffix { + in.endToken(_COMMENT) + return + } + + // Otherwise, save comment for later attachment to syntax tree. + in.endToken(_EOLCOMMENT) + in.comments = append(in.comments, Comment{in.token.pos, in.token.text, suffix}) + return + } + + if in.peekPrefix("/*") { + in.Error("mod files must use // comments (not /* */ comments)") + } + + // Found non-space non-comment. + break + } + + // Found the beginning of the next token. + in.startToken() + + // End of file. + if in.eof() { + in.endToken(_EOF) + return + } + + // Punctuation tokens. + switch c := in.peekRune(); c { + case '\n', '(', ')', '[', ']', '{', '}', ',': + in.readRune() + in.endToken(tokenKind(c)) + return + + case '"', '`': // quoted string + quote := c + in.readRune() + for { + if in.eof() { + in.pos = in.token.pos + in.Error("unexpected EOF in string") + } + if in.peekRune() == '\n' { + in.Error("unexpected newline in string") + } + c := in.readRune() + if c == quote { + break + } + if c == '\\' && quote != '`' { + if in.eof() { + in.pos = in.token.pos + in.Error("unexpected EOF in string") + } + in.readRune() + } + } + in.endToken(_STRING) + return + } + + // Checked all punctuation. Must be identifier token. + if c := in.peekRune(); !isIdent(c) { + in.Error(fmt.Sprintf("unexpected input character %#q", c)) + } + + // Scan over identifier. + for isIdent(in.peekRune()) { + if in.peekPrefix("//") { + break + } + if in.peekPrefix("/*") { + in.Error("mod files must use // comments (not /* */ comments)") + } + in.readRune() + } + in.endToken(_IDENT) +} + +// isIdent reports whether c is an identifier rune. +// We treat most printable runes as identifier runes, except for a handful of +// ASCII punctuation characters. +func isIdent(c int) bool { + switch r := rune(c); r { + case ' ', '(', ')', '[', ']', '{', '}', ',': + return false + default: + return !unicode.IsSpace(r) && unicode.IsPrint(r) + } +} + +// Comment assignment. +// We build two lists of all subexpressions, preorder and postorder. +// The preorder list is ordered by start location, with outer expressions first. +// The postorder list is ordered by end location, with outer expressions last. +// We use the preorder list to assign each whole-line comment to the syntax +// immediately following it, and we use the postorder list to assign each +// end-of-line comment to the syntax immediately preceding it. + +// order walks the expression adding it and its subexpressions to the +// preorder and postorder lists. +func (in *input) order(x Expr) { + if x != nil { + in.pre = append(in.pre, x) + } + switch x := x.(type) { + default: + panic(fmt.Errorf("order: unexpected type %T", x)) + case nil: + // nothing + case *LParen, *RParen: + // nothing + case *CommentBlock: + // nothing + case *Line: + // nothing + case *FileSyntax: + for _, stmt := range x.Stmt { + in.order(stmt) + } + case *LineBlock: + in.order(&x.LParen) + for _, l := range x.Line { + in.order(l) + } + in.order(&x.RParen) + } + if x != nil { + in.post = append(in.post, x) + } +} + +// assignComments attaches comments to nearby syntax. +func (in *input) assignComments() { + const debug = false + + // Generate preorder and postorder lists. + in.order(in.file) + + // Split into whole-line comments and suffix comments. + var line, suffix []Comment + for _, com := range in.comments { + if com.Suffix { + suffix = append(suffix, com) + } else { + line = append(line, com) + } + } + + if debug { + for _, c := range line { + fmt.Fprintf(os.Stderr, "LINE %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) + } + } + + // Assign line comments to syntax immediately following. + for _, x := range in.pre { + start, _ := x.Span() + if debug { + fmt.Fprintf(os.Stderr, "pre %T :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte) + } + xcom := x.Comment() + for len(line) > 0 && start.Byte >= line[0].Start.Byte { + if debug { + fmt.Fprintf(os.Stderr, "ASSIGN LINE %q #%d\n", line[0].Token, line[0].Start.Byte) + } + xcom.Before = append(xcom.Before, line[0]) + line = line[1:] + } + } + + // Remaining line comments go at end of file. + in.file.After = append(in.file.After, line...) + + if debug { + for _, c := range suffix { + fmt.Fprintf(os.Stderr, "SUFFIX %q :%d:%d #%d\n", c.Token, c.Start.Line, c.Start.LineRune, c.Start.Byte) + } + } + + // Assign suffix comments to syntax immediately before. + for i := len(in.post) - 1; i >= 0; i-- { + x := in.post[i] + + start, end := x.Span() + if debug { + fmt.Fprintf(os.Stderr, "post %T :%d:%d #%d :%d:%d #%d\n", x, start.Line, start.LineRune, start.Byte, end.Line, end.LineRune, end.Byte) + } + + // Do not assign suffix comments to end of line block or whole file. + // Instead assign them to the last element inside. + switch x.(type) { + case *FileSyntax: + continue + } + + // Do not assign suffix comments to something that starts + // on an earlier line, so that in + // + // x ( y + // z ) // comment + // + // we assign the comment to z and not to x ( ... ). + if start.Line != end.Line { + continue + } + xcom := x.Comment() + for len(suffix) > 0 && end.Byte <= suffix[len(suffix)-1].Start.Byte { + if debug { + fmt.Fprintf(os.Stderr, "ASSIGN SUFFIX %q #%d\n", suffix[len(suffix)-1].Token, suffix[len(suffix)-1].Start.Byte) + } + xcom.Suffix = append(xcom.Suffix, suffix[len(suffix)-1]) + suffix = suffix[:len(suffix)-1] + } + } + + // We assigned suffix comments in reverse. + // If multiple suffix comments were appended to the same + // expression node, they are now in reverse. Fix that. + for _, x := range in.post { + reverseComments(x.Comment().Suffix) + } + + // Remaining suffix comments go at beginning of file. + in.file.Before = append(in.file.Before, suffix...) +} + +// reverseComments reverses the []Comment list. +func reverseComments(list []Comment) { + for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 { + list[i], list[j] = list[j], list[i] + } +} + +func (in *input) parseFile() { + in.file = new(FileSyntax) + var cb *CommentBlock + for { + switch in.peek() { + case '\n': + in.lex() + if cb != nil { + in.file.Stmt = append(in.file.Stmt, cb) + cb = nil + } + case _COMMENT: + tok := in.lex() + if cb == nil { + cb = &CommentBlock{Start: tok.pos} + } + com := cb.Comment() + com.Before = append(com.Before, Comment{Start: tok.pos, Token: tok.text}) + case _EOF: + if cb != nil { + in.file.Stmt = append(in.file.Stmt, cb) + } + return + default: + in.parseStmt() + if cb != nil { + in.file.Stmt[len(in.file.Stmt)-1].Comment().Before = cb.Before + cb = nil + } + } + } +} + +func (in *input) parseStmt() { + tok := in.lex() + start := tok.pos + end := tok.endPos + tokens := []string{tok.text} + for { + tok := in.lex() + switch { + case tok.kind.isEOL(): + in.file.Stmt = append(in.file.Stmt, &Line{ + Start: start, + Token: tokens, + End: end, + }) + return + + case tok.kind == '(': + if next := in.peek(); next.isEOL() { + // Start of block: no more tokens on this line. + in.file.Stmt = append(in.file.Stmt, in.parseLineBlock(start, tokens, tok)) + return + } else if next == ')' { + rparen := in.lex() + if in.peek().isEOL() { + // Empty block. + in.lex() + in.file.Stmt = append(in.file.Stmt, &LineBlock{ + Start: start, + Token: tokens, + LParen: LParen{Pos: tok.pos}, + RParen: RParen{Pos: rparen.pos}, + }) + return + } + // '( )' in the middle of the line, not a block. + tokens = append(tokens, tok.text, rparen.text) + } else { + // '(' in the middle of the line, not a block. + tokens = append(tokens, tok.text) + } + + default: + tokens = append(tokens, tok.text) + end = tok.endPos + } + } +} + +func (in *input) parseLineBlock(start Position, token []string, lparen token) *LineBlock { + x := &LineBlock{ + Start: start, + Token: token, + LParen: LParen{Pos: lparen.pos}, + } + var comments []Comment + for { + switch in.peek() { + case _EOLCOMMENT: + // Suffix comment, will be attached later by assignComments. + in.lex() + case '\n': + // Blank line. Add an empty comment to preserve it. + in.lex() + if len(comments) == 0 && len(x.Line) > 0 || len(comments) > 0 && comments[len(comments)-1].Token != "" { + comments = append(comments, Comment{}) + } + case _COMMENT: + tok := in.lex() + comments = append(comments, Comment{Start: tok.pos, Token: tok.text}) + case _EOF: + in.Error(fmt.Sprintf("syntax error (unterminated block started at %s:%d:%d)", in.filename, x.Start.Line, x.Start.LineRune)) + case ')': + rparen := in.lex() + x.RParen.Before = comments + x.RParen.Pos = rparen.pos + if !in.peek().isEOL() { + in.Error("syntax error (expected newline after closing paren)") + } + in.lex() + return x + default: + l := in.parseLine() + x.Line = append(x.Line, l) + l.Comment().Before = comments + comments = nil + } + } +} + +func (in *input) parseLine() *Line { + tok := in.lex() + if tok.kind.isEOL() { + in.Error("internal parse error: parseLine at end of line") + } + start := tok.pos + end := tok.endPos + tokens := []string{tok.text} + for { + tok := in.lex() + if tok.kind.isEOL() { + return &Line{ + Start: start, + Token: tokens, + End: end, + InBlock: true, + } + } + tokens = append(tokens, tok.text) + end = tok.endPos + } +} + +var ( + slashSlash = []byte("//") + moduleStr = []byte("module") +) + +// ModulePath returns the module path from the gomod file text. +// If it cannot find a module path, it returns an empty string. +// It is tolerant of unrelated problems in the go.mod file. +func ModulePath(mod []byte) string { + for len(mod) > 0 { + line := mod + mod = nil + if i := bytes.IndexByte(line, '\n'); i >= 0 { + line, mod = line[:i], line[i+1:] + } + if i := bytes.Index(line, slashSlash); i >= 0 { + line = line[:i] + } + line = bytes.TrimSpace(line) + if !bytes.HasPrefix(line, moduleStr) { + continue + } + line = line[len(moduleStr):] + n := len(line) + line = bytes.TrimSpace(line) + if len(line) == n || len(line) == 0 { + continue + } + + if line[0] == '"' || line[0] == '`' { + p, err := strconv.Unquote(string(line)) + if err != nil { + return "" // malformed quoted string or multiline module path + } + return p + } + + return string(line) + } + return "" // missing module path +} diff --git a/vendor/golang.org/x/mod/modfile/rule.go b/vendor/golang.org/x/mod/modfile/rule.go new file mode 100644 index 000000000..ed2f31aa7 --- /dev/null +++ b/vendor/golang.org/x/mod/modfile/rule.go @@ -0,0 +1,1556 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package modfile implements a parser and formatter for go.mod files. +// +// The go.mod syntax is described in +// https://golang.org/cmd/go/#hdr-The_go_mod_file. +// +// The Parse and ParseLax functions both parse a go.mod file and return an +// abstract syntax tree. ParseLax ignores unknown statements and may be used to +// parse go.mod files that may have been developed with newer versions of Go. +// +// The File struct returned by Parse and ParseLax represent an abstract +// go.mod file. File has several methods like AddNewRequire and DropReplace +// that can be used to programmatically edit a file. +// +// The Format function formats a File back to a byte slice which can be +// written to a file. +package modfile + +import ( + "errors" + "fmt" + "path/filepath" + "sort" + "strconv" + "strings" + "unicode" + + "golang.org/x/mod/internal/lazyregexp" + "golang.org/x/mod/module" + "golang.org/x/mod/semver" +) + +// A File is the parsed, interpreted form of a go.mod file. +type File struct { + Module *Module + Go *Go + Require []*Require + Exclude []*Exclude + Replace []*Replace + Retract []*Retract + + Syntax *FileSyntax +} + +// A Module is the module statement. +type Module struct { + Mod module.Version + Deprecated string + Syntax *Line +} + +// A Go is the go statement. +type Go struct { + Version string // "1.23" + Syntax *Line +} + +// An Exclude is a single exclude statement. +type Exclude struct { + Mod module.Version + Syntax *Line +} + +// A Replace is a single replace statement. +type Replace struct { + Old module.Version + New module.Version + Syntax *Line +} + +// A Retract is a single retract statement. +type Retract struct { + VersionInterval + Rationale string + Syntax *Line +} + +// A VersionInterval represents a range of versions with upper and lower bounds. +// Intervals are closed: both bounds are included. When Low is equal to High, +// the interval may refer to a single version ('v1.2.3') or an interval +// ('[v1.2.3, v1.2.3]'); both have the same representation. +type VersionInterval struct { + Low, High string +} + +// A Require is a single require statement. +type Require struct { + Mod module.Version + Indirect bool // has "// indirect" comment + Syntax *Line +} + +func (r *Require) markRemoved() { + r.Syntax.markRemoved() + *r = Require{} +} + +func (r *Require) setVersion(v string) { + r.Mod.Version = v + + if line := r.Syntax; len(line.Token) > 0 { + if line.InBlock { + // If the line is preceded by an empty line, remove it; see + // https://golang.org/issue/33779. + if len(line.Comments.Before) == 1 && len(line.Comments.Before[0].Token) == 0 { + line.Comments.Before = line.Comments.Before[:0] + } + if len(line.Token) >= 2 { // example.com v1.2.3 + line.Token[1] = v + } + } else { + if len(line.Token) >= 3 { // require example.com v1.2.3 + line.Token[2] = v + } + } + } +} + +// setIndirect sets line to have (or not have) a "// indirect" comment. +func (r *Require) setIndirect(indirect bool) { + r.Indirect = indirect + line := r.Syntax + if isIndirect(line) == indirect { + return + } + if indirect { + // Adding comment. + if len(line.Suffix) == 0 { + // New comment. + line.Suffix = []Comment{{Token: "// indirect", Suffix: true}} + return + } + + com := &line.Suffix[0] + text := strings.TrimSpace(strings.TrimPrefix(com.Token, string(slashSlash))) + if text == "" { + // Empty comment. + com.Token = "// indirect" + return + } + + // Insert at beginning of existing comment. + com.Token = "// indirect; " + text + return + } + + // Removing comment. + f := strings.TrimSpace(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash))) + if f == "indirect" { + // Remove whole comment. + line.Suffix = nil + return + } + + // Remove comment prefix. + com := &line.Suffix[0] + i := strings.Index(com.Token, "indirect;") + com.Token = "//" + com.Token[i+len("indirect;"):] +} + +// isIndirect reports whether line has a "// indirect" comment, +// meaning it is in go.mod only for its effect on indirect dependencies, +// so that it can be dropped entirely once the effective version of the +// indirect dependency reaches the given minimum version. +func isIndirect(line *Line) bool { + if len(line.Suffix) == 0 { + return false + } + f := strings.Fields(strings.TrimPrefix(line.Suffix[0].Token, string(slashSlash))) + return (len(f) == 1 && f[0] == "indirect" || len(f) > 1 && f[0] == "indirect;") +} + +func (f *File) AddModuleStmt(path string) error { + if f.Syntax == nil { + f.Syntax = new(FileSyntax) + } + if f.Module == nil { + f.Module = &Module{ + Mod: module.Version{Path: path}, + Syntax: f.Syntax.addLine(nil, "module", AutoQuote(path)), + } + } else { + f.Module.Mod.Path = path + f.Syntax.updateLine(f.Module.Syntax, "module", AutoQuote(path)) + } + return nil +} + +func (f *File) AddComment(text string) { + if f.Syntax == nil { + f.Syntax = new(FileSyntax) + } + f.Syntax.Stmt = append(f.Syntax.Stmt, &CommentBlock{ + Comments: Comments{ + Before: []Comment{ + { + Token: text, + }, + }, + }, + }) +} + +type VersionFixer func(path, version string) (string, error) + +// errDontFix is returned by a VersionFixer to indicate the version should be +// left alone, even if it's not canonical. +var dontFixRetract VersionFixer = func(_, vers string) (string, error) { + return vers, nil +} + +// Parse parses and returns a go.mod file. +// +// file is the name of the file, used in positions and errors. +// +// data is the content of the file. +// +// fix is an optional function that canonicalizes module versions. +// If fix is nil, all module versions must be canonical (module.CanonicalVersion +// must return the same string). +func Parse(file string, data []byte, fix VersionFixer) (*File, error) { + return parseToFile(file, data, fix, true) +} + +// ParseLax is like Parse but ignores unknown statements. +// It is used when parsing go.mod files other than the main module, +// under the theory that most statement types we add in the future will +// only apply in the main module, like exclude and replace, +// and so we get better gradual deployments if old go commands +// simply ignore those statements when found in go.mod files +// in dependencies. +func ParseLax(file string, data []byte, fix VersionFixer) (*File, error) { + return parseToFile(file, data, fix, false) +} + +func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (parsed *File, err error) { + fs, err := parse(file, data) + if err != nil { + return nil, err + } + f := &File{ + Syntax: fs, + } + var errs ErrorList + + // fix versions in retract directives after the file is parsed. + // We need the module path to fix versions, and it might be at the end. + defer func() { + oldLen := len(errs) + f.fixRetract(fix, &errs) + if len(errs) > oldLen { + parsed, err = nil, errs + } + }() + + for _, x := range fs.Stmt { + switch x := x.(type) { + case *Line: + f.add(&errs, nil, x, x.Token[0], x.Token[1:], fix, strict) + + case *LineBlock: + if len(x.Token) > 1 { + if strict { + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + } + continue + } + switch x.Token[0] { + default: + if strict { + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + } + continue + case "module", "require", "exclude", "replace", "retract": + for _, l := range x.Line { + f.add(&errs, x, l, x.Token[0], l.Token, fix, strict) + } + } + } + } + + if len(errs) > 0 { + return nil, errs + } + return f, nil +} + +var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) +var laxGoVersionRE = lazyregexp.New(`^v?(([1-9][0-9]*)\.(0|[1-9][0-9]*))([^0-9].*)$`) + +func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, args []string, fix VersionFixer, strict bool) { + // If strict is false, this module is a dependency. + // We ignore all unknown directives as well as main-module-only + // directives like replace and exclude. It will work better for + // forward compatibility if we can depend on modules that have unknown + // statements (presumed relevant only when acting as the main module) + // and simply ignore those statements. + if !strict { + switch verb { + case "go", "module", "retract", "require": + // want these even for dependency go.mods + default: + return + } + } + + wrapModPathError := func(modPath string, err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: line.Start, + ModPath: modPath, + Verb: verb, + Err: err, + }) + } + wrapError := func(err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: line.Start, + Err: err, + }) + } + errorf := func(format string, args ...interface{}) { + wrapError(fmt.Errorf(format, args...)) + } + + switch verb { + default: + errorf("unknown directive: %s", verb) + + case "go": + if f.Go != nil { + errorf("repeated go statement") + return + } + if len(args) != 1 { + errorf("go directive expects exactly one argument") + return + } else if !GoVersionRE.MatchString(args[0]) { + fixed := false + if !strict { + if m := laxGoVersionRE.FindStringSubmatch(args[0]); m != nil { + args[0] = m[1] + fixed = true + } + } + if !fixed { + errorf("invalid go version '%s': must match format 1.23", args[0]) + return + } + } + + f.Go = &Go{Syntax: line} + f.Go.Version = args[0] + + case "module": + if f.Module != nil { + errorf("repeated module statement") + return + } + deprecated := parseDeprecation(block, line) + f.Module = &Module{ + Syntax: line, + Deprecated: deprecated, + } + if len(args) != 1 { + errorf("usage: module module/path") + return + } + s, err := parseString(&args[0]) + if err != nil { + errorf("invalid quoted string: %v", err) + return + } + f.Module.Mod = module.Version{Path: s} + + case "require", "exclude": + if len(args) != 2 { + errorf("usage: %s module/path v1.2.3", verb) + return + } + s, err := parseString(&args[0]) + if err != nil { + errorf("invalid quoted string: %v", err) + return + } + v, err := parseVersion(verb, s, &args[1], fix) + if err != nil { + wrapError(err) + return + } + pathMajor, err := modulePathMajor(s) + if err != nil { + wrapError(err) + return + } + if err := module.CheckPathMajor(v, pathMajor); err != nil { + wrapModPathError(s, err) + return + } + if verb == "require" { + f.Require = append(f.Require, &Require{ + Mod: module.Version{Path: s, Version: v}, + Syntax: line, + Indirect: isIndirect(line), + }) + } else { + f.Exclude = append(f.Exclude, &Exclude{ + Mod: module.Version{Path: s, Version: v}, + Syntax: line, + }) + } + + case "replace": + replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) + if wrappederr != nil { + *errs = append(*errs, *wrappederr) + return + } + f.Replace = append(f.Replace, replace) + + case "retract": + rationale := parseDirectiveComment(block, line) + vi, err := parseVersionInterval(verb, "", &args, dontFixRetract) + if err != nil { + if strict { + wrapError(err) + return + } else { + // Only report errors parsing intervals in the main module. We may + // support additional syntax in the future, such as open and half-open + // intervals. Those can't be supported now, because they break the + // go.mod parser, even in lax mode. + return + } + } + if len(args) > 0 && strict { + // In the future, there may be additional information after the version. + errorf("unexpected token after version: %q", args[0]) + return + } + retract := &Retract{ + VersionInterval: vi, + Rationale: rationale, + Syntax: line, + } + f.Retract = append(f.Retract, retract) + } +} + +func parseReplace(filename string, line *Line, verb string, args []string, fix VersionFixer) (*Replace, *Error) { + wrapModPathError := func(modPath string, err error) *Error { + return &Error{ + Filename: filename, + Pos: line.Start, + ModPath: modPath, + Verb: verb, + Err: err, + } + } + wrapError := func(err error) *Error { + return &Error{ + Filename: filename, + Pos: line.Start, + Err: err, + } + } + errorf := func(format string, args ...interface{}) *Error { + return wrapError(fmt.Errorf(format, args...)) + } + + arrow := 2 + if len(args) >= 2 && args[1] == "=>" { + arrow = 1 + } + if len(args) < arrow+2 || len(args) > arrow+3 || args[arrow] != "=>" { + return nil, errorf("usage: %s module/path [v1.2.3] => other/module v1.4\n\t or %s module/path [v1.2.3] => ../local/directory", verb, verb) + } + s, err := parseString(&args[0]) + if err != nil { + return nil, errorf("invalid quoted string: %v", err) + } + pathMajor, err := modulePathMajor(s) + if err != nil { + return nil, wrapModPathError(s, err) + + } + var v string + if arrow == 2 { + v, err = parseVersion(verb, s, &args[1], fix) + if err != nil { + return nil, wrapError(err) + } + if err := module.CheckPathMajor(v, pathMajor); err != nil { + return nil, wrapModPathError(s, err) + } + } + ns, err := parseString(&args[arrow+1]) + if err != nil { + return nil, errorf("invalid quoted string: %v", err) + } + nv := "" + if len(args) == arrow+2 { + if !IsDirectoryPath(ns) { + return nil, errorf("replacement module without version must be directory path (rooted or starting with ./ or ../)") + } + if filepath.Separator == '/' && strings.Contains(ns, `\`) { + return nil, errorf("replacement directory appears to be Windows path (on a non-windows system)") + } + } + if len(args) == arrow+3 { + nv, err = parseVersion(verb, ns, &args[arrow+2], fix) + if err != nil { + return nil, wrapError(err) + } + if IsDirectoryPath(ns) { + return nil, errorf("replacement module directory path %q cannot have version", ns) + + } + } + return &Replace{ + Old: module.Version{Path: s, Version: v}, + New: module.Version{Path: ns, Version: nv}, + Syntax: line, + }, nil +} + +// fixRetract applies fix to each retract directive in f, appending any errors +// to errs. +// +// Most versions are fixed as we parse the file, but for retract directives, +// the relevant module path is the one specified with the module directive, +// and that might appear at the end of the file (or not at all). +func (f *File) fixRetract(fix VersionFixer, errs *ErrorList) { + if fix == nil { + return + } + path := "" + if f.Module != nil { + path = f.Module.Mod.Path + } + var r *Retract + wrapError := func(err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: r.Syntax.Start, + Err: err, + }) + } + + for _, r = range f.Retract { + if path == "" { + wrapError(errors.New("no module directive found, so retract cannot be used")) + return // only print the first one of these + } + + args := r.Syntax.Token + if args[0] == "retract" { + args = args[1:] + } + vi, err := parseVersionInterval("retract", path, &args, fix) + if err != nil { + wrapError(err) + } + r.VersionInterval = vi + } +} + +func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string, fix VersionFixer) { + wrapError := func(err error) { + *errs = append(*errs, Error{ + Filename: f.Syntax.Name, + Pos: line.Start, + Err: err, + }) + } + errorf := func(format string, args ...interface{}) { + wrapError(fmt.Errorf(format, args...)) + } + + switch verb { + default: + errorf("unknown directive: %s", verb) + + case "go": + if f.Go != nil { + errorf("repeated go statement") + return + } + if len(args) != 1 { + errorf("go directive expects exactly one argument") + return + } else if !GoVersionRE.MatchString(args[0]) { + errorf("invalid go version '%s': must match format 1.23", args[0]) + return + } + + f.Go = &Go{Syntax: line} + f.Go.Version = args[0] + + case "use": + if len(args) != 1 { + errorf("usage: %s local/dir", verb) + return + } + s, err := parseString(&args[0]) + if err != nil { + errorf("invalid quoted string: %v", err) + return + } + f.Use = append(f.Use, &Use{ + Path: s, + Syntax: line, + }) + + case "replace": + replace, wrappederr := parseReplace(f.Syntax.Name, line, verb, args, fix) + if wrappederr != nil { + *errs = append(*errs, *wrappederr) + return + } + f.Replace = append(f.Replace, replace) + } +} + +// IsDirectoryPath reports whether the given path should be interpreted +// as a directory path. Just like on the go command line, relative paths +// and rooted paths are directory paths; the rest are module paths. +func IsDirectoryPath(ns string) bool { + // Because go.mod files can move from one system to another, + // we check all known path syntaxes, both Unix and Windows. + return strings.HasPrefix(ns, "./") || strings.HasPrefix(ns, "../") || strings.HasPrefix(ns, "/") || + strings.HasPrefix(ns, `.\`) || strings.HasPrefix(ns, `..\`) || strings.HasPrefix(ns, `\`) || + len(ns) >= 2 && ('A' <= ns[0] && ns[0] <= 'Z' || 'a' <= ns[0] && ns[0] <= 'z') && ns[1] == ':' +} + +// MustQuote reports whether s must be quoted in order to appear as +// a single token in a go.mod line. +func MustQuote(s string) bool { + for _, r := range s { + switch r { + case ' ', '"', '\'', '`': + return true + + case '(', ')', '[', ']', '{', '}', ',': + if len(s) > 1 { + return true + } + + default: + if !unicode.IsPrint(r) { + return true + } + } + } + return s == "" || strings.Contains(s, "//") || strings.Contains(s, "/*") +} + +// AutoQuote returns s or, if quoting is required for s to appear in a go.mod, +// the quotation of s. +func AutoQuote(s string) string { + if MustQuote(s) { + return strconv.Quote(s) + } + return s +} + +func parseVersionInterval(verb string, path string, args *[]string, fix VersionFixer) (VersionInterval, error) { + toks := *args + if len(toks) == 0 || toks[0] == "(" { + return VersionInterval{}, fmt.Errorf("expected '[' or version") + } + if toks[0] != "[" { + v, err := parseVersion(verb, path, &toks[0], fix) + if err != nil { + return VersionInterval{}, err + } + *args = toks[1:] + return VersionInterval{Low: v, High: v}, nil + } + toks = toks[1:] + + if len(toks) == 0 { + return VersionInterval{}, fmt.Errorf("expected version after '['") + } + low, err := parseVersion(verb, path, &toks[0], fix) + if err != nil { + return VersionInterval{}, err + } + toks = toks[1:] + + if len(toks) == 0 || toks[0] != "," { + return VersionInterval{}, fmt.Errorf("expected ',' after version") + } + toks = toks[1:] + + if len(toks) == 0 { + return VersionInterval{}, fmt.Errorf("expected version after ','") + } + high, err := parseVersion(verb, path, &toks[0], fix) + if err != nil { + return VersionInterval{}, err + } + toks = toks[1:] + + if len(toks) == 0 || toks[0] != "]" { + return VersionInterval{}, fmt.Errorf("expected ']' after version") + } + toks = toks[1:] + + *args = toks + return VersionInterval{Low: low, High: high}, nil +} + +func parseString(s *string) (string, error) { + t := *s + if strings.HasPrefix(t, `"`) { + var err error + if t, err = strconv.Unquote(t); err != nil { + return "", err + } + } else if strings.ContainsAny(t, "\"'`") { + // Other quotes are reserved both for possible future expansion + // and to avoid confusion. For example if someone types 'x' + // we want that to be a syntax error and not a literal x in literal quotation marks. + return "", fmt.Errorf("unquoted string cannot contain quote") + } + *s = AutoQuote(t) + return t, nil +} + +var deprecatedRE = lazyregexp.New(`(?s)(?:^|\n\n)Deprecated: *(.*?)(?:$|\n\n)`) + +// parseDeprecation extracts the text of comments on a "module" directive and +// extracts a deprecation message from that. +// +// A deprecation message is contained in a paragraph within a block of comments +// that starts with "Deprecated:" (case sensitive). The message runs until the +// end of the paragraph and does not include the "Deprecated:" prefix. If the +// comment block has multiple paragraphs that start with "Deprecated:", +// parseDeprecation returns the message from the first. +func parseDeprecation(block *LineBlock, line *Line) string { + text := parseDirectiveComment(block, line) + m := deprecatedRE.FindStringSubmatch(text) + if m == nil { + return "" + } + return m[1] +} + +// parseDirectiveComment extracts the text of comments on a directive. +// If the directive's line does not have comments and is part of a block that +// does have comments, the block's comments are used. +func parseDirectiveComment(block *LineBlock, line *Line) string { + comments := line.Comment() + if block != nil && len(comments.Before) == 0 && len(comments.Suffix) == 0 { + comments = block.Comment() + } + groups := [][]Comment{comments.Before, comments.Suffix} + var lines []string + for _, g := range groups { + for _, c := range g { + if !strings.HasPrefix(c.Token, "//") { + continue // blank line + } + lines = append(lines, strings.TrimSpace(strings.TrimPrefix(c.Token, "//"))) + } + } + return strings.Join(lines, "\n") +} + +type ErrorList []Error + +func (e ErrorList) Error() string { + errStrs := make([]string, len(e)) + for i, err := range e { + errStrs[i] = err.Error() + } + return strings.Join(errStrs, "\n") +} + +type Error struct { + Filename string + Pos Position + Verb string + ModPath string + Err error +} + +func (e *Error) Error() string { + var pos string + if e.Pos.LineRune > 1 { + // Don't print LineRune if it's 1 (beginning of line). + // It's always 1 except in scanner errors, which are rare. + pos = fmt.Sprintf("%s:%d:%d: ", e.Filename, e.Pos.Line, e.Pos.LineRune) + } else if e.Pos.Line > 0 { + pos = fmt.Sprintf("%s:%d: ", e.Filename, e.Pos.Line) + } else if e.Filename != "" { + pos = fmt.Sprintf("%s: ", e.Filename) + } + + var directive string + if e.ModPath != "" { + directive = fmt.Sprintf("%s %s: ", e.Verb, e.ModPath) + } else if e.Verb != "" { + directive = fmt.Sprintf("%s: ", e.Verb) + } + + return pos + directive + e.Err.Error() +} + +func (e *Error) Unwrap() error { return e.Err } + +func parseVersion(verb string, path string, s *string, fix VersionFixer) (string, error) { + t, err := parseString(s) + if err != nil { + return "", &Error{ + Verb: verb, + ModPath: path, + Err: &module.InvalidVersionError{ + Version: *s, + Err: err, + }, + } + } + if fix != nil { + fixed, err := fix(path, t) + if err != nil { + if err, ok := err.(*module.ModuleError); ok { + return "", &Error{ + Verb: verb, + ModPath: path, + Err: err.Err, + } + } + return "", err + } + t = fixed + } else { + cv := module.CanonicalVersion(t) + if cv == "" { + return "", &Error{ + Verb: verb, + ModPath: path, + Err: &module.InvalidVersionError{ + Version: t, + Err: errors.New("must be of the form v1.2.3"), + }, + } + } + t = cv + } + *s = t + return *s, nil +} + +func modulePathMajor(path string) (string, error) { + _, major, ok := module.SplitPathVersion(path) + if !ok { + return "", fmt.Errorf("invalid module path") + } + return major, nil +} + +func (f *File) Format() ([]byte, error) { + return Format(f.Syntax), nil +} + +// Cleanup cleans up the file f after any edit operations. +// To avoid quadratic behavior, modifications like DropRequire +// clear the entry but do not remove it from the slice. +// Cleanup cleans out all the cleared entries. +func (f *File) Cleanup() { + w := 0 + for _, r := range f.Require { + if r.Mod.Path != "" { + f.Require[w] = r + w++ + } + } + f.Require = f.Require[:w] + + w = 0 + for _, x := range f.Exclude { + if x.Mod.Path != "" { + f.Exclude[w] = x + w++ + } + } + f.Exclude = f.Exclude[:w] + + w = 0 + for _, r := range f.Replace { + if r.Old.Path != "" { + f.Replace[w] = r + w++ + } + } + f.Replace = f.Replace[:w] + + w = 0 + for _, r := range f.Retract { + if r.Low != "" || r.High != "" { + f.Retract[w] = r + w++ + } + } + f.Retract = f.Retract[:w] + + f.Syntax.Cleanup() +} + +func (f *File) AddGoStmt(version string) error { + if !GoVersionRE.MatchString(version) { + return fmt.Errorf("invalid language version string %q", version) + } + if f.Go == nil { + var hint Expr + if f.Module != nil && f.Module.Syntax != nil { + hint = f.Module.Syntax + } + f.Go = &Go{ + Version: version, + Syntax: f.Syntax.addLine(hint, "go", version), + } + } else { + f.Go.Version = version + f.Syntax.updateLine(f.Go.Syntax, "go", version) + } + return nil +} + +// AddRequire sets the first require line for path to version vers, +// preserving any existing comments for that line and removing all +// other lines for path. +// +// If no line currently exists for path, AddRequire adds a new line +// at the end of the last require block. +func (f *File) AddRequire(path, vers string) error { + need := true + for _, r := range f.Require { + if r.Mod.Path == path { + if need { + r.Mod.Version = vers + f.Syntax.updateLine(r.Syntax, "require", AutoQuote(path), vers) + need = false + } else { + r.Syntax.markRemoved() + *r = Require{} + } + } + } + + if need { + f.AddNewRequire(path, vers, false) + } + return nil +} + +// AddNewRequire adds a new require line for path at version vers at the end of +// the last require block, regardless of any existing require lines for path. +func (f *File) AddNewRequire(path, vers string, indirect bool) { + line := f.Syntax.addLine(nil, "require", AutoQuote(path), vers) + r := &Require{ + Mod: module.Version{Path: path, Version: vers}, + Syntax: line, + } + r.setIndirect(indirect) + f.Require = append(f.Require, r) +} + +// SetRequire updates the requirements of f to contain exactly req, preserving +// the existing block structure and line comment contents (except for 'indirect' +// markings) for the first requirement on each named module path. +// +// The Syntax field is ignored for the requirements in req. +// +// Any requirements not already present in the file are added to the block +// containing the last require line. +// +// The requirements in req must specify at most one distinct version for each +// module path. +// +// If any existing requirements may be removed, the caller should call Cleanup +// after all edits are complete. +func (f *File) SetRequire(req []*Require) { + type elem struct { + version string + indirect bool + } + need := make(map[string]elem) + for _, r := range req { + if prev, dup := need[r.Mod.Path]; dup && prev.version != r.Mod.Version { + panic(fmt.Errorf("SetRequire called with conflicting versions for path %s (%s and %s)", r.Mod.Path, prev.version, r.Mod.Version)) + } + need[r.Mod.Path] = elem{r.Mod.Version, r.Indirect} + } + + // Update or delete the existing Require entries to preserve + // only the first for each module path in req. + for _, r := range f.Require { + e, ok := need[r.Mod.Path] + if ok { + r.setVersion(e.version) + r.setIndirect(e.indirect) + } else { + r.markRemoved() + } + delete(need, r.Mod.Path) + } + + // Add new entries in the last block of the file for any paths that weren't + // already present. + // + // This step is nondeterministic, but the final result will be deterministic + // because we will sort the block. + for path, e := range need { + f.AddNewRequire(path, e.version, e.indirect) + } + + f.SortBlocks() +} + +// SetRequireSeparateIndirect updates the requirements of f to contain the given +// requirements. Comment contents (except for 'indirect' markings) are retained +// from the first existing requirement for each module path. Like SetRequire, +// SetRequireSeparateIndirect adds requirements for new paths in req, +// updates the version and "// indirect" comment on existing requirements, +// and deletes requirements on paths not in req. Existing duplicate requirements +// are deleted. +// +// As its name suggests, SetRequireSeparateIndirect puts direct and indirect +// requirements into two separate blocks, one containing only direct +// requirements, and the other containing only indirect requirements. +// SetRequireSeparateIndirect may move requirements between these two blocks +// when their indirect markings change. However, SetRequireSeparateIndirect +// won't move requirements from other blocks, especially blocks with comments. +// +// If the file initially has one uncommented block of requirements, +// SetRequireSeparateIndirect will split it into a direct-only and indirect-only +// block. This aids in the transition to separate blocks. +func (f *File) SetRequireSeparateIndirect(req []*Require) { + // hasComments returns whether a line or block has comments + // other than "indirect". + hasComments := func(c Comments) bool { + return len(c.Before) > 0 || len(c.After) > 0 || len(c.Suffix) > 1 || + (len(c.Suffix) == 1 && + strings.TrimSpace(strings.TrimPrefix(c.Suffix[0].Token, string(slashSlash))) != "indirect") + } + + // moveReq adds r to block. If r was in another block, moveReq deletes + // it from that block and transfers its comments. + moveReq := func(r *Require, block *LineBlock) { + var line *Line + if r.Syntax == nil { + line = &Line{Token: []string{AutoQuote(r.Mod.Path), r.Mod.Version}} + r.Syntax = line + if r.Indirect { + r.setIndirect(true) + } + } else { + line = new(Line) + *line = *r.Syntax + if !line.InBlock && len(line.Token) > 0 && line.Token[0] == "require" { + line.Token = line.Token[1:] + } + r.Syntax.Token = nil // Cleanup will delete the old line. + r.Syntax = line + } + line.InBlock = true + block.Line = append(block.Line, line) + } + + // Examine existing require lines and blocks. + var ( + // We may insert new requirements into the last uncommented + // direct-only and indirect-only blocks. We may also move requirements + // to the opposite block if their indirect markings change. + lastDirectIndex = -1 + lastIndirectIndex = -1 + + // If there are no direct-only or indirect-only blocks, a new block may + // be inserted after the last require line or block. + lastRequireIndex = -1 + + // If there's only one require line or block, and it's uncommented, + // we'll move its requirements to the direct-only or indirect-only blocks. + requireLineOrBlockCount = 0 + + // Track the block each requirement belongs to (if any) so we can + // move them later. + lineToBlock = make(map[*Line]*LineBlock) + ) + for i, stmt := range f.Syntax.Stmt { + switch stmt := stmt.(type) { + case *Line: + if len(stmt.Token) == 0 || stmt.Token[0] != "require" { + continue + } + lastRequireIndex = i + requireLineOrBlockCount++ + if !hasComments(stmt.Comments) { + if isIndirect(stmt) { + lastIndirectIndex = i + } else { + lastDirectIndex = i + } + } + + case *LineBlock: + if len(stmt.Token) == 0 || stmt.Token[0] != "require" { + continue + } + lastRequireIndex = i + requireLineOrBlockCount++ + allDirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments) + allIndirect := len(stmt.Line) > 0 && !hasComments(stmt.Comments) + for _, line := range stmt.Line { + lineToBlock[line] = stmt + if hasComments(line.Comments) { + allDirect = false + allIndirect = false + } else if isIndirect(line) { + allDirect = false + } else { + allIndirect = false + } + } + if allDirect { + lastDirectIndex = i + } + if allIndirect { + lastIndirectIndex = i + } + } + } + + oneFlatUncommentedBlock := requireLineOrBlockCount == 1 && + !hasComments(*f.Syntax.Stmt[lastRequireIndex].Comment()) + + // Create direct and indirect blocks if needed. Convert lines into blocks + // if needed. If we end up with an empty block or a one-line block, + // Cleanup will delete it or convert it to a line later. + insertBlock := func(i int) *LineBlock { + block := &LineBlock{Token: []string{"require"}} + f.Syntax.Stmt = append(f.Syntax.Stmt, nil) + copy(f.Syntax.Stmt[i+1:], f.Syntax.Stmt[i:]) + f.Syntax.Stmt[i] = block + return block + } + + ensureBlock := func(i int) *LineBlock { + switch stmt := f.Syntax.Stmt[i].(type) { + case *LineBlock: + return stmt + case *Line: + block := &LineBlock{ + Token: []string{"require"}, + Line: []*Line{stmt}, + } + stmt.Token = stmt.Token[1:] // remove "require" + stmt.InBlock = true + f.Syntax.Stmt[i] = block + return block + default: + panic(fmt.Sprintf("unexpected statement: %v", stmt)) + } + } + + var lastDirectBlock *LineBlock + if lastDirectIndex < 0 { + if lastIndirectIndex >= 0 { + lastDirectIndex = lastIndirectIndex + lastIndirectIndex++ + } else if lastRequireIndex >= 0 { + lastDirectIndex = lastRequireIndex + 1 + } else { + lastDirectIndex = len(f.Syntax.Stmt) + } + lastDirectBlock = insertBlock(lastDirectIndex) + } else { + lastDirectBlock = ensureBlock(lastDirectIndex) + } + + var lastIndirectBlock *LineBlock + if lastIndirectIndex < 0 { + lastIndirectIndex = lastDirectIndex + 1 + lastIndirectBlock = insertBlock(lastIndirectIndex) + } else { + lastIndirectBlock = ensureBlock(lastIndirectIndex) + } + + // Delete requirements we don't want anymore. + // Update versions and indirect comments on requirements we want to keep. + // If a requirement is in last{Direct,Indirect}Block with the wrong + // indirect marking after this, or if the requirement is in an single + // uncommented mixed block (oneFlatUncommentedBlock), move it to the + // correct block. + // + // Some blocks may be empty after this. Cleanup will remove them. + need := make(map[string]*Require) + for _, r := range req { + need[r.Mod.Path] = r + } + have := make(map[string]*Require) + for _, r := range f.Require { + path := r.Mod.Path + if need[path] == nil || have[path] != nil { + // Requirement not needed, or duplicate requirement. Delete. + r.markRemoved() + continue + } + have[r.Mod.Path] = r + r.setVersion(need[path].Mod.Version) + r.setIndirect(need[path].Indirect) + if need[path].Indirect && + (oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastDirectBlock) { + moveReq(r, lastIndirectBlock) + } else if !need[path].Indirect && + (oneFlatUncommentedBlock || lineToBlock[r.Syntax] == lastIndirectBlock) { + moveReq(r, lastDirectBlock) + } + } + + // Add new requirements. + for path, r := range need { + if have[path] == nil { + if r.Indirect { + moveReq(r, lastIndirectBlock) + } else { + moveReq(r, lastDirectBlock) + } + f.Require = append(f.Require, r) + } + } + + f.SortBlocks() +} + +func (f *File) DropRequire(path string) error { + for _, r := range f.Require { + if r.Mod.Path == path { + r.Syntax.markRemoved() + *r = Require{} + } + } + return nil +} + +// AddExclude adds a exclude statement to the mod file. Errors if the provided +// version is not a canonical version string +func (f *File) AddExclude(path, vers string) error { + if err := checkCanonicalVersion(path, vers); err != nil { + return err + } + + var hint *Line + for _, x := range f.Exclude { + if x.Mod.Path == path && x.Mod.Version == vers { + return nil + } + if x.Mod.Path == path { + hint = x.Syntax + } + } + + f.Exclude = append(f.Exclude, &Exclude{Mod: module.Version{Path: path, Version: vers}, Syntax: f.Syntax.addLine(hint, "exclude", AutoQuote(path), vers)}) + return nil +} + +func (f *File) DropExclude(path, vers string) error { + for _, x := range f.Exclude { + if x.Mod.Path == path && x.Mod.Version == vers { + x.Syntax.markRemoved() + *x = Exclude{} + } + } + return nil +} + +func (f *File) AddReplace(oldPath, oldVers, newPath, newVers string) error { + return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) +} + +func addReplace(syntax *FileSyntax, replace *[]*Replace, oldPath, oldVers, newPath, newVers string) error { + need := true + old := module.Version{Path: oldPath, Version: oldVers} + new := module.Version{Path: newPath, Version: newVers} + tokens := []string{"replace", AutoQuote(oldPath)} + if oldVers != "" { + tokens = append(tokens, oldVers) + } + tokens = append(tokens, "=>", AutoQuote(newPath)) + if newVers != "" { + tokens = append(tokens, newVers) + } + + var hint *Line + for _, r := range *replace { + if r.Old.Path == oldPath && (oldVers == "" || r.Old.Version == oldVers) { + if need { + // Found replacement for old; update to use new. + r.New = new + syntax.updateLine(r.Syntax, tokens...) + need = false + continue + } + // Already added; delete other replacements for same. + r.Syntax.markRemoved() + *r = Replace{} + } + if r.Old.Path == oldPath { + hint = r.Syntax + } + } + if need { + *replace = append(*replace, &Replace{Old: old, New: new, Syntax: syntax.addLine(hint, tokens...)}) + } + return nil +} + +func (f *File) DropReplace(oldPath, oldVers string) error { + for _, r := range f.Replace { + if r.Old.Path == oldPath && r.Old.Version == oldVers { + r.Syntax.markRemoved() + *r = Replace{} + } + } + return nil +} + +// AddRetract adds a retract statement to the mod file. Errors if the provided +// version interval does not consist of canonical version strings +func (f *File) AddRetract(vi VersionInterval, rationale string) error { + var path string + if f.Module != nil { + path = f.Module.Mod.Path + } + if err := checkCanonicalVersion(path, vi.High); err != nil { + return err + } + if err := checkCanonicalVersion(path, vi.Low); err != nil { + return err + } + + r := &Retract{ + VersionInterval: vi, + } + if vi.Low == vi.High { + r.Syntax = f.Syntax.addLine(nil, "retract", AutoQuote(vi.Low)) + } else { + r.Syntax = f.Syntax.addLine(nil, "retract", "[", AutoQuote(vi.Low), ",", AutoQuote(vi.High), "]") + } + if rationale != "" { + for _, line := range strings.Split(rationale, "\n") { + com := Comment{Token: "// " + line} + r.Syntax.Comment().Before = append(r.Syntax.Comment().Before, com) + } + } + return nil +} + +func (f *File) DropRetract(vi VersionInterval) error { + for _, r := range f.Retract { + if r.VersionInterval == vi { + r.Syntax.markRemoved() + *r = Retract{} + } + } + return nil +} + +func (f *File) SortBlocks() { + f.removeDups() // otherwise sorting is unsafe + + for _, stmt := range f.Syntax.Stmt { + block, ok := stmt.(*LineBlock) + if !ok { + continue + } + less := lineLess + if block.Token[0] == "retract" { + less = lineRetractLess + } + sort.SliceStable(block.Line, func(i, j int) bool { + return less(block.Line[i], block.Line[j]) + }) + } +} + +// removeDups removes duplicate exclude and replace directives. +// +// Earlier exclude directives take priority. +// +// Later replace directives take priority. +// +// require directives are not de-duplicated. That's left up to higher-level +// logic (MVS). +// +// retract directives are not de-duplicated since comments are +// meaningful, and versions may be retracted multiple times. +func (f *File) removeDups() { + removeDups(f.Syntax, &f.Exclude, &f.Replace) +} + +func removeDups(syntax *FileSyntax, exclude *[]*Exclude, replace *[]*Replace) { + kill := make(map[*Line]bool) + + // Remove duplicate excludes. + if exclude != nil { + haveExclude := make(map[module.Version]bool) + for _, x := range *exclude { + if haveExclude[x.Mod] { + kill[x.Syntax] = true + continue + } + haveExclude[x.Mod] = true + } + var excl []*Exclude + for _, x := range *exclude { + if !kill[x.Syntax] { + excl = append(excl, x) + } + } + *exclude = excl + } + + // Remove duplicate replacements. + // Later replacements take priority over earlier ones. + haveReplace := make(map[module.Version]bool) + for i := len(*replace) - 1; i >= 0; i-- { + x := (*replace)[i] + if haveReplace[x.Old] { + kill[x.Syntax] = true + continue + } + haveReplace[x.Old] = true + } + var repl []*Replace + for _, x := range *replace { + if !kill[x.Syntax] { + repl = append(repl, x) + } + } + *replace = repl + + // Duplicate require and retract directives are not removed. + + // Drop killed statements from the syntax tree. + var stmts []Expr + for _, stmt := range syntax.Stmt { + switch stmt := stmt.(type) { + case *Line: + if kill[stmt] { + continue + } + case *LineBlock: + var lines []*Line + for _, line := range stmt.Line { + if !kill[line] { + lines = append(lines, line) + } + } + stmt.Line = lines + if len(lines) == 0 { + continue + } + } + stmts = append(stmts, stmt) + } + syntax.Stmt = stmts +} + +// lineLess returns whether li should be sorted before lj. It sorts +// lexicographically without assigning any special meaning to tokens. +func lineLess(li, lj *Line) bool { + for k := 0; k < len(li.Token) && k < len(lj.Token); k++ { + if li.Token[k] != lj.Token[k] { + return li.Token[k] < lj.Token[k] + } + } + return len(li.Token) < len(lj.Token) +} + +// lineRetractLess returns whether li should be sorted before lj for lines in +// a "retract" block. It treats each line as a version interval. Single versions +// are compared as if they were intervals with the same low and high version. +// Intervals are sorted in descending order, first by low version, then by +// high version, using semver.Compare. +func lineRetractLess(li, lj *Line) bool { + interval := func(l *Line) VersionInterval { + if len(l.Token) == 1 { + return VersionInterval{Low: l.Token[0], High: l.Token[0]} + } else if len(l.Token) == 5 && l.Token[0] == "[" && l.Token[2] == "," && l.Token[4] == "]" { + return VersionInterval{Low: l.Token[1], High: l.Token[3]} + } else { + // Line in unknown format. Treat as an invalid version. + return VersionInterval{} + } + } + vii := interval(li) + vij := interval(lj) + if cmp := semver.Compare(vii.Low, vij.Low); cmp != 0 { + return cmp > 0 + } + return semver.Compare(vii.High, vij.High) > 0 +} + +// checkCanonicalVersion returns a non-nil error if vers is not a canonical +// version string or does not match the major version of path. +// +// If path is non-empty, the error text suggests a format with a major version +// corresponding to the path. +func checkCanonicalVersion(path, vers string) error { + _, pathMajor, pathMajorOk := module.SplitPathVersion(path) + + if vers == "" || vers != module.CanonicalVersion(vers) { + if pathMajor == "" { + return &module.InvalidVersionError{ + Version: vers, + Err: fmt.Errorf("must be of the form v1.2.3"), + } + } + return &module.InvalidVersionError{ + Version: vers, + Err: fmt.Errorf("must be of the form %s.2.3", module.PathMajorPrefix(pathMajor)), + } + } + + if pathMajorOk { + if err := module.CheckPathMajor(vers, pathMajor); err != nil { + if pathMajor == "" { + // In this context, the user probably wrote "v2.3.4" when they meant + // "v2.3.4+incompatible". Suggest that instead of "v0 or v1". + return &module.InvalidVersionError{ + Version: vers, + Err: fmt.Errorf("should be %s+incompatible (or module %s/%v)", vers, path, semver.Major(vers)), + } + } + return err + } + } + + return nil +} diff --git a/vendor/golang.org/x/mod/modfile/work.go b/vendor/golang.org/x/mod/modfile/work.go new file mode 100644 index 000000000..0c0e52152 --- /dev/null +++ b/vendor/golang.org/x/mod/modfile/work.go @@ -0,0 +1,234 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package modfile + +import ( + "fmt" + "sort" + "strings" +) + +// A WorkFile is the parsed, interpreted form of a go.work file. +type WorkFile struct { + Go *Go + Use []*Use + Replace []*Replace + + Syntax *FileSyntax +} + +// A Use is a single directory statement. +type Use struct { + Path string // Use path of module. + ModulePath string // Module path in the comment. + Syntax *Line +} + +// ParseWork parses and returns a go.work file. +// +// file is the name of the file, used in positions and errors. +// +// data is the content of the file. +// +// fix is an optional function that canonicalizes module versions. +// If fix is nil, all module versions must be canonical (module.CanonicalVersion +// must return the same string). +func ParseWork(file string, data []byte, fix VersionFixer) (*WorkFile, error) { + fs, err := parse(file, data) + if err != nil { + return nil, err + } + f := &WorkFile{ + Syntax: fs, + } + var errs ErrorList + + for _, x := range fs.Stmt { + switch x := x.(type) { + case *Line: + f.add(&errs, x, x.Token[0], x.Token[1:], fix) + + case *LineBlock: + if len(x.Token) > 1 { + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + continue + } + switch x.Token[0] { + default: + errs = append(errs, Error{ + Filename: file, + Pos: x.Start, + Err: fmt.Errorf("unknown block type: %s", strings.Join(x.Token, " ")), + }) + continue + case "use", "replace": + for _, l := range x.Line { + f.add(&errs, l, x.Token[0], l.Token, fix) + } + } + } + } + + if len(errs) > 0 { + return nil, errs + } + return f, nil +} + +// Cleanup cleans up the file f after any edit operations. +// To avoid quadratic behavior, modifications like DropRequire +// clear the entry but do not remove it from the slice. +// Cleanup cleans out all the cleared entries. +func (f *WorkFile) Cleanup() { + w := 0 + for _, r := range f.Use { + if r.Path != "" { + f.Use[w] = r + w++ + } + } + f.Use = f.Use[:w] + + w = 0 + for _, r := range f.Replace { + if r.Old.Path != "" { + f.Replace[w] = r + w++ + } + } + f.Replace = f.Replace[:w] + + f.Syntax.Cleanup() +} + +func (f *WorkFile) AddGoStmt(version string) error { + if !GoVersionRE.MatchString(version) { + return fmt.Errorf("invalid language version string %q", version) + } + if f.Go == nil { + stmt := &Line{Token: []string{"go", version}} + f.Go = &Go{ + Version: version, + Syntax: stmt, + } + // Find the first non-comment-only block that's and add + // the go statement before it. That will keep file comments at the top. + i := 0 + for i = 0; i < len(f.Syntax.Stmt); i++ { + if _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok { + break + } + } + f.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...) + } else { + f.Go.Version = version + f.Syntax.updateLine(f.Go.Syntax, "go", version) + } + return nil +} + +func (f *WorkFile) AddUse(diskPath, modulePath string) error { + need := true + for _, d := range f.Use { + if d.Path == diskPath { + if need { + d.ModulePath = modulePath + f.Syntax.updateLine(d.Syntax, "use", AutoQuote(diskPath)) + need = false + } else { + d.Syntax.markRemoved() + *d = Use{} + } + } + } + + if need { + f.AddNewUse(diskPath, modulePath) + } + return nil +} + +func (f *WorkFile) AddNewUse(diskPath, modulePath string) { + line := f.Syntax.addLine(nil, "use", AutoQuote(diskPath)) + f.Use = append(f.Use, &Use{Path: diskPath, ModulePath: modulePath, Syntax: line}) +} + +func (f *WorkFile) SetUse(dirs []*Use) { + need := make(map[string]string) + for _, d := range dirs { + need[d.Path] = d.ModulePath + } + + for _, d := range f.Use { + if modulePath, ok := need[d.Path]; ok { + d.ModulePath = modulePath + } else { + d.Syntax.markRemoved() + *d = Use{} + } + } + + // TODO(#45713): Add module path to comment. + + for diskPath, modulePath := range need { + f.AddNewUse(diskPath, modulePath) + } + f.SortBlocks() +} + +func (f *WorkFile) DropUse(path string) error { + for _, d := range f.Use { + if d.Path == path { + d.Syntax.markRemoved() + *d = Use{} + } + } + return nil +} + +func (f *WorkFile) AddReplace(oldPath, oldVers, newPath, newVers string) error { + return addReplace(f.Syntax, &f.Replace, oldPath, oldVers, newPath, newVers) +} + +func (f *WorkFile) DropReplace(oldPath, oldVers string) error { + for _, r := range f.Replace { + if r.Old.Path == oldPath && r.Old.Version == oldVers { + r.Syntax.markRemoved() + *r = Replace{} + } + } + return nil +} + +func (f *WorkFile) SortBlocks() { + f.removeDups() // otherwise sorting is unsafe + + for _, stmt := range f.Syntax.Stmt { + block, ok := stmt.(*LineBlock) + if !ok { + continue + } + sort.SliceStable(block.Line, func(i, j int) bool { + return lineLess(block.Line[i], block.Line[j]) + }) + } +} + +// removeDups removes duplicate replace directives. +// +// Later replace directives take priority. +// +// require directives are not de-duplicated. That's left up to higher-level +// logic (MVS). +// +// retract directives are not de-duplicated since comments are +// meaningful, and versions may be retracted multiple times. +func (f *WorkFile) removeDups() { + removeDups(f.Syntax, nil, &f.Replace) +} diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/golang.org/x/net/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/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/golang.org/x/net/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/net/bpf/vm_instructions.go b/vendor/golang.org/x/net/bpf/vm_instructions.go index cf8947c33..0aa307c06 100644 --- a/vendor/golang.org/x/net/bpf/vm_instructions.go +++ b/vendor/golang.org/x/net/bpf/vm_instructions.go @@ -94,7 +94,7 @@ func jumpIfCommon(cond JumpTest, skipTrue, skipFalse uint8, regA uint32, value u func loadAbsolute(ins LoadAbsolute, in []byte) (uint32, bool) { offset := int(ins.Off) - size := int(ins.Size) + size := ins.Size return loadCommon(in, offset, size) } @@ -121,7 +121,7 @@ func loadExtension(ins LoadExtension, in []byte) uint32 { func loadIndirect(ins LoadIndirect, in []byte, regX uint32) (uint32, bool) { offset := int(ins.Off) + int(regX) - size := int(ins.Size) + size := ins.Size return loadCommon(in, offset, size) } diff --git a/vendor/golang.org/x/net/context/go17.go b/vendor/golang.org/x/net/context/go17.go index 0a54bdbcc..2cb9c408f 100644 --- a/vendor/golang.org/x/net/context/go17.go +++ b/vendor/golang.org/x/net/context/go17.go @@ -32,7 +32,7 @@ var DeadlineExceeded = context.DeadlineExceeded // call cancel as soon as the operations running in this Context complete. func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { ctx, f := context.WithCancel(parent) - return ctx, CancelFunc(f) + return ctx, f } // WithDeadline returns a copy of the parent context with the deadline adjusted @@ -46,7 +46,7 @@ func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { // call cancel as soon as the operations running in this Context complete. func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { ctx, f := context.WithDeadline(parent, deadline) - return ctx, CancelFunc(f) + return ctx, f } // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). diff --git a/vendor/golang.org/x/net/dns/dnsmessage/message.go b/vendor/golang.org/x/net/dns/dnsmessage/message.go index 0cdf89f9f..ffdf19d5d 100644 --- a/vendor/golang.org/x/net/dns/dnsmessage/message.go +++ b/vendor/golang.org/x/net/dns/dnsmessage/message.go @@ -317,6 +317,8 @@ type Header struct { Truncated bool RecursionDesired bool RecursionAvailable bool + AuthenticData bool + CheckingDisabled bool RCode RCode } @@ -338,6 +340,12 @@ func (m *Header) pack() (id uint16, bits uint16) { if m.Response { bits |= headerBitQR } + if m.AuthenticData { + bits |= headerBitAD + } + if m.CheckingDisabled { + bits |= headerBitCD + } return } @@ -379,6 +387,8 @@ const ( headerBitTC = 1 << 9 // truncated headerBitRD = 1 << 8 // recursion desired headerBitRA = 1 << 7 // recursion available + headerBitAD = 1 << 5 // authentic data + headerBitCD = 1 << 4 // checking disabled ) var sectionNames = map[section]string{ @@ -456,6 +466,8 @@ func (h *header) header() Header { Truncated: (h.bits & headerBitTC) != 0, RecursionDesired: (h.bits & headerBitRD) != 0, RecursionAvailable: (h.bits & headerBitRA) != 0, + AuthenticData: (h.bits & headerBitAD) != 0, + CheckingDisabled: (h.bits & headerBitCD) != 0, RCode: RCode(h.bits & 0xF), } } @@ -1887,11 +1899,11 @@ type Name struct { // NewName creates a new Name from a string. func NewName(name string) (Name, error) { - if len([]byte(name)) > nameLen { + if len(name) > nameLen { return Name{}, errCalcLen } n := Name{Length: uint8(len(name))} - copy(n.Data[:], []byte(name)) + copy(n.Data[:], name) return n, nil } diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go index b46d81ca6..497e13204 100644 --- a/vendor/golang.org/x/net/html/render.go +++ b/vendor/golang.org/x/net/html/render.go @@ -85,7 +85,7 @@ func render1(w writer, n *Node) error { if _, err := w.WriteString(""); err != nil { @@ -96,7 +96,7 @@ func render1(w writer, n *Node) error { if _, err := w.WriteString("" case CommentToken: - return "" + return "" case DoctypeToken: - return "" + return "" } return "Invalid(" + strconv.Itoa(int(t.Type)) + ")" } diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go index ba53f564b..f7d0b0d2b 100644 --- a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go +++ b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go @@ -8,22 +8,21 @@ package socket import ( + "net" "os" ) func (c *Conn) recvMsg(m *Message, flags int) error { m.raceWrite() - var h msghdr - vs := make([]iovec, len(m.Buffers)) - var sa []byte - if c.network != "tcp" { - sa = make([]byte, sizeofSockaddrInet6) - } - h.pack(vs, m.Buffers, m.OOB, sa) - var operr error - var n int + var ( + operr error + n int + oobn int + recvflags int + from net.Addr + ) fn := func(s uintptr) bool { - n, operr = recvmsg(s, &h, flags) + n, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network) return ioComplete(flags, operr) } if err := c.c.Read(fn); err != nil { @@ -32,34 +31,21 @@ func (c *Conn) recvMsg(m *Message, flags int) error { if operr != nil { return os.NewSyscallError("recvmsg", operr) } - if c.network != "tcp" { - var err error - m.Addr, err = parseInetAddr(sa[:], c.network) - if err != nil { - return err - } - } + m.Addr = from m.N = n - m.NN = h.controllen() - m.Flags = h.flags() + m.NN = oobn + m.Flags = recvflags return nil } func (c *Conn) sendMsg(m *Message, flags int) error { m.raceRead() - var h msghdr - vs := make([]iovec, len(m.Buffers)) - var sa []byte - if m.Addr != nil { - var a [sizeofSockaddrInet6]byte - n := marshalInetAddr(m.Addr, a[:]) - sa = a[:n] - } - h.pack(vs, m.Buffers, m.OOB, sa) - var operr error - var n int + var ( + operr error + n int + ) fn := func(s uintptr) bool { - n, operr = sendmsg(s, &h, flags) + n, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags) return ioComplete(flags, operr) } if err := c.c.Write(fn); err != nil { diff --git a/vendor/golang.org/x/net/internal/socket/sys_stub.go b/vendor/golang.org/x/net/internal/socket/sys_stub.go index 381e45e16..7cfb349c0 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_stub.go +++ b/vendor/golang.org/x/net/internal/socket/sys_stub.go @@ -36,11 +36,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return errNotImplemented } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errNotImplemented +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + return 0, 0, 0, nil, errNotImplemented } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go index d203e2984..de823932b 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_unix.go +++ b/vendor/golang.org/x/net/internal/socket/sys_unix.go @@ -8,8 +8,10 @@ package socket import ( - "syscall" + "net" "unsafe" + + "golang.org/x/sys/unix" ) //go:linkname syscall_getsockopt syscall.getsockopt @@ -18,12 +20,6 @@ func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) //go:linkname syscall_setsockopt syscall.setsockopt func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error -//go:linkname syscall_recvmsg syscall.recvmsg -func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (int, error) - -//go:linkname syscall_sendmsg syscall.sendmsg -func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (int, error) - func getsockopt(s uintptr, level, name int, b []byte) (int, error) { l := uint32(len(b)) err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l) @@ -34,10 +30,93 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b))) } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + var unixFrom unix.Sockaddr + n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags) + if unixFrom != nil { + from = sockaddrToAddr(unixFrom, network) + } + return } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { + var unixTo unix.Sockaddr + if to != nil { + unixTo = addrToSockaddr(to) + } + return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags) +} + +// addrToSockaddr converts a net.Addr to a unix.Sockaddr. +func addrToSockaddr(a net.Addr) unix.Sockaddr { + var ( + ip net.IP + port int + zone string + ) + switch a := a.(type) { + case *net.TCPAddr: + ip = a.IP + port = a.Port + zone = a.Zone + case *net.UDPAddr: + ip = a.IP + port = a.Port + zone = a.Zone + case *net.IPAddr: + ip = a.IP + zone = a.Zone + default: + return nil + } + + if ip4 := ip.To4(); ip4 != nil { + sa := unix.SockaddrInet4{Port: port} + copy(sa.Addr[:], ip4) + return &sa + } + + if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil { + sa := unix.SockaddrInet6{Port: port} + copy(sa.Addr[:], ip6) + if zone != "" { + sa.ZoneId = uint32(zoneCache.index(zone)) + } + return &sa + } + + return nil +} + +// sockaddrToAddr converts a unix.Sockaddr to a net.Addr. +func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr { + var ( + ip net.IP + port int + zone string + ) + switch sa := sa.(type) { + case *unix.SockaddrInet4: + ip = make(net.IP, net.IPv4len) + copy(ip, sa.Addr[:]) + port = sa.Port + case *unix.SockaddrInet6: + ip = make(net.IP, net.IPv6len) + copy(ip, sa.Addr[:]) + port = sa.Port + if sa.ZoneId > 0 { + zone = zoneCache.name(int(sa.ZoneId)) + } + default: + return nil + } + + switch network { + case "tcp", "tcp4", "tcp6": + return &net.TCPAddr{IP: ip, Port: port, Zone: zone} + case "udp", "udp4", "udp6": + return &net.UDPAddr{IP: ip, Port: port, Zone: zone} + default: + return &net.IPAddr{IP: ip, Zone: zone} + } } diff --git a/vendor/golang.org/x/net/internal/socket/sys_windows.go b/vendor/golang.org/x/net/internal/socket/sys_windows.go index 2de0d68c6..b738b89dd 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_windows.go +++ b/vendor/golang.org/x/net/internal/socket/sys_windows.go @@ -5,6 +5,7 @@ package socket import ( + "net" "syscall" "unsafe" @@ -37,11 +38,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b))) } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errNotImplemented +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + return 0, 0, 0, nil, errNotImplemented } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go index 1e38b9223..eaa896cb5 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go +++ b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go @@ -5,6 +5,7 @@ package socket import ( + "net" "syscall" "unsafe" ) @@ -27,12 +28,39 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return errnoErr(errno) } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) - return int(n), errnoErr(errno) +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + var h msghdr + vs := make([]iovec, len(buffers)) + var sa []byte + if network != "tcp" { + sa = make([]byte, sizeofSockaddrInet6) + } + h.pack(vs, buffers, oob, sa) + sn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags)) + n = int(sn) + oobn = h.controllen() + recvflags = h.flags() + err = errnoErr(errno) + if network != "tcp" { + var err2 error + from, err2 = parseInetAddr(sa, network) + if err2 != nil && err == nil { + err = err2 + } + } + return } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { + var h msghdr + vs := make([]iovec, len(buffers)) + var sa []byte + if to != nil { + var a [sizeofSockaddrInet6]byte + n := marshalInetAddr(to, a[:]) + sa = a[:n] + } + h.pack(vs, buffers, oob, sa) + n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags)) return int(n), errnoErr(errno) } diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go deleted file mode 100644 index 5acf6db6e..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_darwin.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go similarity index 79% rename from vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go rename to vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go index 5acf6db6e..965c0b28b 100644 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go +++ b/vendor/golang.org/x/net/internal/socket/zsys_freebsd_riscv64.go @@ -1,11 +1,11 @@ // Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_darwin.go +// cgo -godefs defs_freebsd.go package socket type iovec struct { Base *byte - Len uint32 + Len uint64 } type msghdr struct { @@ -25,6 +25,6 @@ type cmsghdr struct { } const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c + sizeofIovec = 0x10 + sizeofMsghdr = 0x30 ) diff --git a/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go b/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go new file mode 100644 index 000000000..0feb9a753 --- /dev/null +++ b/vendor/golang.org/x/net/ipv4/zsys_freebsd_riscv64.go @@ -0,0 +1,52 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_freebsd.go + +package ipv4 + +const ( + sizeofSockaddrStorage = 0x80 + sizeofSockaddrInet = 0x10 + + sizeofIPMreq = 0x8 + sizeofIPMreqSource = 0xc + sizeofGroupReq = 0x88 + sizeofGroupSourceReq = 0x108 +) + +type sockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]uint8 + X__ss_align int64 + X__ss_pad2 [112]uint8 +} + +type sockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]uint8 +} + +type ipMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type ipMreqSource struct { + Multiaddr [4]byte /* in_addr */ + Sourceaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type groupReq struct { + Interface uint32 + Group sockaddrStorage +} + +type groupSourceReq struct { + Interface uint32 + Group sockaddrStorage + Source sockaddrStorage +} diff --git a/vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go b/vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go new file mode 100644 index 000000000..5b39eb8df --- /dev/null +++ b/vendor/golang.org/x/net/ipv6/zsys_freebsd_riscv64.go @@ -0,0 +1,64 @@ +// Code generated by cmd/cgo -godefs; DO NOT EDIT. +// cgo -godefs defs_freebsd.go + +package ipv6 + +const ( + sizeofSockaddrStorage = 0x80 + sizeofSockaddrInet6 = 0x1c + sizeofInet6Pktinfo = 0x14 + sizeofIPv6Mtuinfo = 0x20 + + sizeofIPv6Mreq = 0x14 + sizeofGroupReq = 0x88 + sizeofGroupSourceReq = 0x108 + + sizeofICMPv6Filter = 0x20 +) + +type sockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]uint8 + X__ss_align int64 + X__ss_pad2 [112]uint8 +} + +type sockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type inet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type ipv6Mtuinfo struct { + Addr sockaddrInet6 + Mtu uint32 +} + +type ipv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type groupReq struct { + Interface uint32 + Group sockaddrStorage +} + +type groupSourceReq struct { + Interface uint32 + Group sockaddrStorage + Source sockaddrStorage +} + +type icmpv6Filter struct { + Filt [8]uint32 +} diff --git a/vendor/golang.org/x/net/route/address.go b/vendor/golang.org/x/net/route/address.go index 1898ed0fa..5a3cc0654 100644 --- a/vendor/golang.org/x/net/route/address.go +++ b/vendor/golang.org/x/net/route/address.go @@ -7,7 +7,10 @@ package route -import "runtime" +import ( + "runtime" + "syscall" +) // An Addr represents an address associated with packet routing. type Addr interface { @@ -23,7 +26,7 @@ type LinkAddr struct { } // Family implements the Family method of Addr interface. -func (a *LinkAddr) Family() int { return sysAF_LINK } +func (a *LinkAddr) Family() int { return syscall.AF_LINK } func (a *LinkAddr) lenAndSpace() (int, int) { l := 8 + len(a.Name) + len(a.Addr) @@ -40,7 +43,7 @@ func (a *LinkAddr) marshal(b []byte) (int, error) { return 0, errInvalidAddr } b[0] = byte(l) - b[1] = sysAF_LINK + b[1] = syscall.AF_LINK if a.Index > 0 { nativeEndian.PutUint16(b[2:4], uint16(a.Index)) } @@ -62,7 +65,7 @@ func parseLinkAddr(b []byte) (Addr, error) { if len(b) < 8 { return nil, errInvalidAddr } - _, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:]) + _, a, err := parseKernelLinkAddr(syscall.AF_LINK, b[4:]) if err != nil { return nil, err } @@ -122,7 +125,7 @@ type Inet4Addr struct { } // Family implements the Family method of Addr interface. -func (a *Inet4Addr) Family() int { return sysAF_INET } +func (a *Inet4Addr) Family() int { return syscall.AF_INET } func (a *Inet4Addr) lenAndSpace() (int, int) { return sizeofSockaddrInet, roundup(sizeofSockaddrInet) @@ -134,7 +137,7 @@ func (a *Inet4Addr) marshal(b []byte) (int, error) { return 0, errShortBuffer } b[0] = byte(l) - b[1] = sysAF_INET + b[1] = syscall.AF_INET copy(b[4:8], a.IP[:]) return ll, nil } @@ -146,7 +149,7 @@ type Inet6Addr struct { } // Family implements the Family method of Addr interface. -func (a *Inet6Addr) Family() int { return sysAF_INET6 } +func (a *Inet6Addr) Family() int { return syscall.AF_INET6 } func (a *Inet6Addr) lenAndSpace() (int, int) { return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6) @@ -158,7 +161,7 @@ func (a *Inet6Addr) marshal(b []byte) (int, error) { return 0, errShortBuffer } b[0] = byte(l) - b[1] = sysAF_INET6 + b[1] = syscall.AF_INET6 copy(b[8:24], a.IP[:]) if a.ZoneID > 0 { nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID)) @@ -169,14 +172,14 @@ func (a *Inet6Addr) marshal(b []byte) (int, error) { // parseInetAddr parses b as an internet address for IPv4 or IPv6. func parseInetAddr(af int, b []byte) (Addr, error) { switch af { - case sysAF_INET: + case syscall.AF_INET: if len(b) < sizeofSockaddrInet { return nil, errInvalidAddr } a := &Inet4Addr{} copy(a.IP[:], b[4:8]) return a, nil - case sysAF_INET6: + case syscall.AF_INET6: if len(b) < sizeofSockaddrInet6 { return nil, errInvalidAddr } @@ -245,7 +248,7 @@ func parseKernelInetAddr(af int, b []byte) (int, Addr, error) { a := &Inet6Addr{} copy(a.IP[:], b[off6:off6+16]) return int(b[0]), a, nil - case af == sysAF_INET6: + case af == syscall.AF_INET6: a := &Inet6Addr{} if l-1 < off6 { copy(a.IP[:], b[1:l]) @@ -365,15 +368,15 @@ func marshalAddrs(b []byte, as []Addr) (uint, error) { } func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) { - var as [sysRTAX_MAX]Addr - af := int(sysAF_UNSPEC) - for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ { + var as [syscall.RTAX_MAX]Addr + af := int(syscall.AF_UNSPEC) + for i := uint(0); i < syscall.RTAX_MAX && len(b) >= roundup(0); i++ { if attrs&(1<= uint16(id) @@ -328,7 +328,7 @@ func (r Region) IsPrivateUse() bool { return r.typ()&iso3166UserAssigned != 0 } -type Script uint8 +type Script uint16 // getScriptID returns the script id for string s. It assumes that s // is of the format [A-Z][a-z]{3}. diff --git a/vendor/golang.org/x/text/internal/language/parse.go b/vendor/golang.org/x/text/internal/language/parse.go index 47ee0fed1..aad1e0acf 100644 --- a/vendor/golang.org/x/text/internal/language/parse.go +++ b/vendor/golang.org/x/text/internal/language/parse.go @@ -270,7 +270,7 @@ func parse(scan *scanner, s string) (t Tag, err error) { } else if n >= 4 { return Und, ErrSyntax } else { // the usual case - t, end = parseTag(scan) + t, end = parseTag(scan, true) if n := len(scan.token); n == 1 { t.pExt = uint16(end) end = parseExtensions(scan) @@ -296,7 +296,8 @@ func parse(scan *scanner, s string) (t Tag, err error) { // parseTag parses language, script, region and variants. // It returns a Tag and the end position in the input that was parsed. -func parseTag(scan *scanner) (t Tag, end int) { +// If doNorm is true, then - will be normalized to . +func parseTag(scan *scanner, doNorm bool) (t Tag, end int) { var e error // TODO: set an error if an unknown lang, script or region is encountered. t.LangID, e = getLangID(scan.token) @@ -307,14 +308,17 @@ func parseTag(scan *scanner) (t Tag, end int) { for len(scan.token) == 3 && isAlpha(scan.token[0]) { // From http://tools.ietf.org/html/bcp47, - tags are equivalent // to a tag of the form . - lang, e := getLangID(scan.token) - if lang != 0 { - t.LangID = lang - copy(scan.b[langStart:], lang.String()) - scan.b[langStart+3] = '-' - scan.start = langStart + 4 + if doNorm { + lang, e := getLangID(scan.token) + if lang != 0 { + t.LangID = lang + langStr := lang.String() + copy(scan.b[langStart:], langStr) + scan.b[langStart+len(langStr)] = '-' + scan.start = langStart + len(langStr) + 1 + } + scan.gobble(e) } - scan.gobble(e) end = scan.scan() } if len(scan.token) == 4 && isAlpha(scan.token[0]) { @@ -559,7 +563,7 @@ func parseExtension(scan *scanner) int { case 't': // https://www.ietf.org/rfc/rfc6497.txt scan.scan() if n := len(scan.token); n >= 2 && n <= 3 && isAlpha(scan.token[1]) { - _, end = parseTag(scan) + _, end = parseTag(scan, false) scan.toLower(start, end) } for len(scan.token) == 2 && !isAlpha(scan.token[1]) { diff --git a/vendor/golang.org/x/text/internal/language/tables.go b/vendor/golang.org/x/text/internal/language/tables.go index a19480c5b..fb6b58378 100644 --- a/vendor/golang.org/x/text/internal/language/tables.go +++ b/vendor/golang.org/x/text/internal/language/tables.go @@ -7,9 +7,9 @@ import "golang.org/x/text/internal/tag" // CLDRVersion is the CLDR version from which the tables in this package are derived. const CLDRVersion = "32" -const NumLanguages = 8717 +const NumLanguages = 8752 -const NumScripts = 251 +const NumScripts = 258 const NumRegions = 357 @@ -121,9 +121,10 @@ const langPrivateEnd = 0x3179 // lang holds an alphabetically sorted list of ISO-639 language identifiers. // All entries are 4 bytes. The index of the identifier (divided by 4) is the language tag. // For 2-byte language identifiers, the two successive bytes have the following meaning: -// - if the first letter of the 2- and 3-letter ISO codes are the same: -// the second and third letter of the 3-letter ISO code. -// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3. +// - if the first letter of the 2- and 3-letter ISO codes are the same: +// the second and third letter of the 3-letter ISO code. +// - otherwise: a 0 and a by 2 bits right-shifted index into altLangISO3. +// // For 3-byte language identifiers the 4th byte is 0. const lang tag.Index = "" + // Size: 5324 bytes "---\x00aaaraai\x00aak\x00aau\x00abbkabi\x00abq\x00abr\x00abt\x00aby\x00a" + @@ -265,7 +266,7 @@ var langNoIndex = [2197]uint8{ 0xad, 0x03, 0xff, 0xff, 0xcf, 0x05, 0x84, 0x62, 0xe9, 0xbf, 0xfd, 0xbf, 0xbf, 0xf7, 0xfd, 0x77, 0x0f, 0xff, 0xef, 0x6f, 0xff, 0xfb, 0xdf, 0xe2, - 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xb8, 0x0a, 0x6a, + 0xc9, 0xf8, 0x7f, 0x7e, 0x4d, 0xbc, 0x0a, 0x6a, 0x7c, 0xea, 0xe3, 0xfa, 0x7a, 0xbf, 0x67, 0xff, // Entry 40 - 7F 0xff, 0xff, 0xff, 0xdf, 0x2a, 0x54, 0x91, 0xc0, @@ -277,7 +278,7 @@ var langNoIndex = [2197]uint8{ 0xa8, 0xff, 0x1f, 0x67, 0x7d, 0xeb, 0xef, 0xce, 0xff, 0xff, 0x9f, 0xff, 0xb7, 0xef, 0xfe, 0xcf, // Entry 80 - BF - 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x2f, 0xff, 0xff, + 0xdb, 0xff, 0xf3, 0xcd, 0xfb, 0x6f, 0xff, 0xff, 0xbb, 0xee, 0xf7, 0xbd, 0xdb, 0xff, 0x5f, 0xf7, 0xfd, 0xf2, 0xfd, 0xff, 0x5e, 0x2f, 0x3b, 0xba, 0x7e, 0xff, 0xff, 0xfe, 0xf7, 0xff, 0xdd, 0xff, @@ -290,15 +291,15 @@ var langNoIndex = [2197]uint8{ 0x1b, 0x14, 0x08, 0xf3, 0x2b, 0xe7, 0x17, 0x56, 0x05, 0x7d, 0x0e, 0x1c, 0x37, 0x7b, 0xf3, 0xef, 0x97, 0xff, 0x5d, 0x38, 0x64, 0x08, 0x00, 0x10, - 0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x73, 0x35, - 0x3e, 0x87, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00, + 0xbc, 0x85, 0xaf, 0xdf, 0xff, 0xff, 0x7b, 0x35, + 0x3e, 0xc7, 0xc7, 0xdf, 0xff, 0x01, 0x81, 0x00, 0xb0, 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x40, 0x00, 0x40, 0x92, 0x21, 0x50, 0xb1, 0x5d, // Entry 100 - 13F 0xfd, 0xdc, 0xbe, 0x5e, 0x00, 0x00, 0x02, 0x64, 0x0d, 0x19, 0x41, 0xdf, 0x79, 0x22, 0x00, 0x00, 0x00, 0x5e, 0x64, 0xdc, 0x24, 0xe5, 0xd9, 0xe3, - 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x01, 0x0c, + 0xfe, 0xff, 0xfd, 0xcb, 0x9f, 0x14, 0x41, 0x0c, 0x86, 0x00, 0xd1, 0x00, 0xf0, 0xc7, 0x67, 0x5f, 0x56, 0x99, 0x5e, 0xb5, 0x6c, 0xaf, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc0, 0x37, 0xda, 0x56, @@ -309,9 +310,9 @@ var langNoIndex = [2197]uint8{ 0x0a, 0x00, 0x01, 0x00, 0x00, 0x10, 0x11, 0x09, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x44, 0x00, 0x00, 0x10, 0x00, 0x04, - 0x08, 0x00, 0x00, 0x04, 0x00, 0x80, 0x28, 0x04, + 0x08, 0x00, 0x00, 0x05, 0x00, 0x80, 0x28, 0x04, 0x00, 0x00, 0x40, 0xd5, 0x2d, 0x00, 0x64, 0x35, - 0x24, 0x52, 0xf4, 0xd4, 0xbd, 0x62, 0xc9, 0x03, + 0x24, 0x52, 0xf4, 0xd5, 0xbf, 0x62, 0xc9, 0x03, // Entry 180 - 1BF 0x00, 0x80, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x13, 0x39, 0x01, 0xdd, 0x57, 0x98, @@ -333,20 +334,20 @@ var langNoIndex = [2197]uint8{ // Entry 200 - 23F 0xdf, 0xc3, 0x83, 0x82, 0xc0, 0xfb, 0x57, 0x27, 0xed, 0x55, 0xe7, 0x01, 0x00, 0x20, 0xb2, 0xc5, - 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe0, 0xdf, - 0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x01, 0xe3, + 0xa4, 0x45, 0x25, 0x9b, 0x02, 0xdf, 0xe1, 0xdf, + 0x03, 0x44, 0x08, 0x90, 0x01, 0x04, 0x81, 0xe3, 0x92, 0x54, 0xdb, 0x28, 0xd3, 0x5f, 0xfe, 0x6d, 0x79, 0xed, 0x1c, 0x7d, 0x04, 0x08, 0x00, 0x01, 0x21, 0x12, 0x64, 0x5f, 0xdd, 0x0e, 0x85, 0x4f, 0x40, 0x40, 0x00, 0x04, 0xf1, 0xfd, 0x3d, 0x54, // Entry 240 - 27F 0xe8, 0x03, 0xb4, 0x27, 0x23, 0x0d, 0x00, 0x00, - 0x20, 0x7b, 0x78, 0x02, 0x05, 0x84, 0x00, 0xf0, + 0x20, 0x7b, 0x78, 0x02, 0x07, 0x84, 0x00, 0xf0, 0xbb, 0x7e, 0x5a, 0x00, 0x18, 0x04, 0x81, 0x00, 0x00, 0x00, 0x80, 0x10, 0x90, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x04, 0x08, 0xa0, 0x70, 0xa5, 0x0c, 0x40, 0x00, 0x00, - 0x11, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff, + 0x91, 0x24, 0x04, 0x68, 0x00, 0x20, 0x70, 0xff, 0x7b, 0x7f, 0x70, 0x00, 0x05, 0x9b, 0xdd, 0x66, // Entry 280 - 2BF 0x03, 0x00, 0x11, 0x00, 0x00, 0x00, 0x40, 0x05, @@ -365,12 +366,12 @@ var langNoIndex = [2197]uint8{ 0xa7, 0x81, 0x47, 0x97, 0xfb, 0x00, 0x10, 0x00, 0x08, 0x00, 0x80, 0x00, 0x40, 0x04, 0x00, 0x01, 0x02, 0x00, 0x01, 0x40, 0x80, 0x00, 0x00, 0x08, - 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x89, 0x12, 0x00, + 0xd8, 0xeb, 0xf6, 0x39, 0xc4, 0x8d, 0x12, 0x00, // Entry 300 - 33F 0x00, 0x0c, 0x04, 0x01, 0x20, 0x20, 0xdd, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x04, 0x10, 0xd0, 0x9d, 0x95, 0x13, 0x04, 0x80, - 0x00, 0x01, 0xd0, 0x12, 0x40, 0x00, 0x10, 0xb0, + 0x00, 0x01, 0xd0, 0x16, 0x40, 0x00, 0x10, 0xb0, 0x10, 0x62, 0x4c, 0xd2, 0x02, 0x01, 0x4a, 0x00, 0x46, 0x04, 0x00, 0x08, 0x02, 0x00, 0x20, 0x80, 0x00, 0x80, 0x06, 0x00, 0x08, 0x00, 0x00, 0x00, @@ -397,9 +398,9 @@ var langNoIndex = [2197]uint8{ 0x02, 0x30, 0x9f, 0x7a, 0x16, 0xbd, 0x7f, 0x57, 0xf2, 0xff, 0x31, 0xff, 0xf2, 0x1e, 0x90, 0xf7, 0xf1, 0xf9, 0x45, 0x80, 0x01, 0x02, 0x00, 0x00, - 0x40, 0x54, 0x9f, 0x8a, 0xd9, 0xf9, 0x2e, 0x11, + 0x40, 0x54, 0x9f, 0x8a, 0xdb, 0xf9, 0x2e, 0x11, 0x86, 0x51, 0xc0, 0xf3, 0xfb, 0x47, 0x40, 0x01, - 0x05, 0xd1, 0x50, 0x5c, 0x00, 0x00, 0x00, 0x10, + 0x05, 0xd1, 0x50, 0x5c, 0x00, 0x40, 0x00, 0x10, 0x04, 0x02, 0x00, 0x00, 0x0a, 0x00, 0x17, 0xd2, 0xb9, 0xfd, 0xfc, 0xba, 0xfe, 0xef, 0xc7, 0xbe, // Entry 400 - 43F @@ -421,19 +422,19 @@ var langNoIndex = [2197]uint8{ 0xcd, 0xff, 0xfb, 0xff, 0xdf, 0xd7, 0xea, 0xff, 0xe5, 0x5f, 0x6d, 0x0f, 0xa7, 0x51, 0x06, 0xc4, // Entry 480 - 4BF - 0x13, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb, + 0x93, 0x50, 0x5d, 0xaf, 0xa6, 0xff, 0x99, 0xfb, 0x63, 0x1d, 0x53, 0xff, 0xef, 0xb7, 0x35, 0x20, 0x14, 0x00, 0x55, 0x51, 0x82, 0x65, 0xf5, 0x41, 0xe2, 0xff, 0xfc, 0xdf, 0x02, 0x05, 0xc5, 0x05, - 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x04, + 0x00, 0x22, 0x00, 0x74, 0x69, 0x10, 0x08, 0x05, 0x41, 0x00, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x20, 0x05, 0x04, 0x01, 0x00, 0x00, - 0x06, 0x01, 0x20, 0x00, 0x18, 0x01, 0x92, 0xb1, + 0x06, 0x01, 0x20, 0x00, 0x18, 0x01, 0x92, 0xf1, // Entry 4C0 - 4FF - 0xfd, 0x47, 0x49, 0x06, 0x95, 0x06, 0x57, 0xed, - 0xfb, 0x4c, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40, + 0xfd, 0x47, 0x69, 0x06, 0x95, 0x06, 0x57, 0xed, + 0xfb, 0x4d, 0x1c, 0x6b, 0x83, 0x04, 0x62, 0x40, 0x00, 0x11, 0x42, 0x00, 0x00, 0x00, 0x54, 0x83, - 0xb8, 0x4f, 0x10, 0x8c, 0x89, 0x46, 0xde, 0xf7, + 0xb8, 0x4f, 0x10, 0x8e, 0x89, 0x46, 0xde, 0xf7, 0x13, 0x31, 0x00, 0x20, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0xf0, 0x5b, 0xf4, 0xbe, 0x3d, @@ -470,7 +471,7 @@ var langNoIndex = [2197]uint8{ 0xaa, 0x10, 0x5d, 0x98, 0x52, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02, 0x02, 0x19, 0x00, 0x10, 0x02, 0x10, 0x61, 0x5a, 0x9d, - 0x31, 0x00, 0x00, 0x00, 0x01, 0x10, 0x02, 0x20, + 0x31, 0x00, 0x00, 0x00, 0x01, 0x18, 0x02, 0x20, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0x20, 0x00, 0x00, 0x1f, 0xdf, 0xd2, 0xb9, 0xff, 0xfd, 0x3f, 0x1f, 0x98, 0xcf, 0x9c, 0xff, 0xaf, 0x5f, 0xfe, @@ -479,9 +480,9 @@ var langNoIndex = [2197]uint8{ 0xb7, 0xf6, 0xfb, 0xb3, 0xc7, 0xff, 0x6f, 0xf1, 0x73, 0xb1, 0x7f, 0x9f, 0x7f, 0xbd, 0xfc, 0xb7, 0xee, 0x1c, 0xfa, 0xcb, 0xef, 0xdd, 0xf9, 0xbd, - 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x1f, + 0x6e, 0xae, 0x55, 0xfd, 0x6e, 0x81, 0x76, 0x9f, 0xd4, 0x77, 0xf5, 0x7d, 0xfb, 0xff, 0xeb, 0xfe, - 0xbe, 0x5f, 0x46, 0x1b, 0xe9, 0x5f, 0x50, 0x18, + 0xbe, 0x5f, 0x46, 0x5b, 0xe9, 0x5f, 0x50, 0x18, 0x02, 0xfa, 0xf7, 0x9d, 0x15, 0x97, 0x05, 0x0f, // Entry 640 - 67F 0x75, 0xc4, 0x7d, 0x81, 0x92, 0xf5, 0x57, 0x6c, @@ -495,14 +496,14 @@ var langNoIndex = [2197]uint8{ // Entry 680 - 6BF 0x97, 0x9d, 0xbf, 0x9f, 0xf7, 0xc7, 0xfd, 0x37, 0xce, 0x7f, 0x04, 0x1d, 0x73, 0x7f, 0xf8, 0xda, - 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x69, 0xa0, + 0x5d, 0xce, 0x7d, 0x06, 0xb9, 0xea, 0x79, 0xa0, 0x1a, 0x20, 0x00, 0x30, 0x02, 0x04, 0x24, 0x08, 0x04, 0x00, 0x00, 0x40, 0xd4, 0x02, 0x04, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x20, 0x01, 0x06, 0x50, 0x00, 0x08, 0x00, 0x00, 0x00, 0x24, 0x00, 0x04, 0x00, 0x10, 0xdc, 0x58, 0xd7, 0x0d, 0x0f, // Entry 6C0 - 6FF - 0x14, 0x4d, 0xf1, 0x16, 0x44, 0xd1, 0x42, 0x08, + 0x14, 0x4d, 0xf1, 0x16, 0x44, 0xd5, 0x42, 0x08, 0x40, 0x00, 0x00, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0xdc, 0xfb, 0xcb, 0x0e, 0x58, 0x48, 0x41, 0x24, 0x20, 0x04, 0x00, 0x30, 0x12, 0x40, 0x00, @@ -513,7 +514,7 @@ var langNoIndex = [2197]uint8{ // Entry 700 - 73F 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x80, 0x86, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x01, - 0xdf, 0x18, 0x00, 0x00, 0x02, 0xf0, 0xfd, 0x79, + 0xff, 0x18, 0x02, 0x00, 0x02, 0xf0, 0xfd, 0x79, 0x3b, 0x00, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x03, 0x00, 0x09, 0x20, 0x00, 0x00, 0x01, 0x00, @@ -525,7 +526,7 @@ var langNoIndex = [2197]uint8{ 0xcd, 0xf9, 0x5c, 0x00, 0x01, 0x00, 0x30, 0x04, 0x04, 0x55, 0x00, 0x01, 0x04, 0xf4, 0x3f, 0x4a, 0x01, 0x00, 0x00, 0xb0, 0x80, 0x20, 0x55, 0x75, - 0x97, 0x7c, 0x9f, 0x31, 0xcc, 0x68, 0xd1, 0x03, + 0x97, 0x7c, 0xdf, 0x31, 0xcc, 0x68, 0xd1, 0x03, 0xd5, 0x57, 0x27, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xf7, 0xcb, 0x1f, 0x14, 0x60, // Entry 780 - 7BF @@ -538,7 +539,7 @@ var langNoIndex = [2197]uint8{ 0xe8, 0x30, 0x90, 0x6a, 0x92, 0x00, 0x00, 0x02, 0xff, 0xef, 0xff, 0x4b, 0x85, 0x53, 0xf4, 0xed, // Entry 7C0 - 7FF - 0xdd, 0xbf, 0x72, 0x1d, 0xc7, 0x0c, 0xd5, 0x42, + 0xdd, 0xbf, 0xf2, 0x5d, 0xc7, 0x0c, 0xd5, 0x42, 0xfc, 0xff, 0xf7, 0x1f, 0x00, 0x80, 0x40, 0x56, 0xcc, 0x16, 0x9e, 0xea, 0x35, 0x7d, 0xef, 0xff, 0xbd, 0xa4, 0xaf, 0x01, 0x44, 0x18, 0x01, 0x4d, @@ -552,15 +553,15 @@ var langNoIndex = [2197]uint8{ 0x40, 0x9c, 0x44, 0xdf, 0xf5, 0x8f, 0x66, 0xb3, 0x55, 0x20, 0xd4, 0xc1, 0xd8, 0x30, 0x3d, 0x80, 0x00, 0x00, 0x00, 0x04, 0xd4, 0x11, 0xc5, 0x84, - 0x2e, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93, + 0x2f, 0x50, 0x00, 0x22, 0x50, 0x6e, 0xbd, 0x93, 0x07, 0x00, 0x20, 0x10, 0x84, 0xb2, 0x45, 0x10, 0x06, 0x44, 0x00, 0x00, 0x12, 0x02, 0x11, 0x00, // Entry 840 - 87F - 0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x12, 0x81, + 0xf0, 0xfb, 0xfd, 0x7f, 0x05, 0x00, 0x16, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, 0x02, 0x28, 0x84, 0x00, 0x21, 0xc0, 0x23, 0x24, 0x00, 0x00, - 0x00, 0xcb, 0xe4, 0x3a, 0x42, 0x88, 0x14, 0xf1, + 0x00, 0xcb, 0xe4, 0x3a, 0x46, 0x88, 0x14, 0xf1, 0xef, 0xff, 0x7f, 0x12, 0x01, 0x01, 0x84, 0x50, 0x07, 0xfc, 0xff, 0xff, 0x0f, 0x01, 0x00, 0x40, 0x10, 0x38, 0x01, 0x01, 0x1c, 0x12, 0x40, 0xe1, @@ -582,8 +583,8 @@ var altLangIndex = [6]uint16{ } // AliasMap maps langIDs to their suggested replacements. -// Size: 704 bytes, 176 elements -var AliasMap = [176]FromTo{ +// Size: 716 bytes, 179 elements +var AliasMap = [179]FromTo{ 0: {From: 0x82, To: 0x88}, 1: {From: 0x187, To: 0x1ae}, 2: {From: 0x1f3, To: 0x1e1}, @@ -612,172 +613,176 @@ var AliasMap = [176]FromTo{ 25: {From: 0x80c, To: 0x5a}, 26: {From: 0x815, To: 0x8d}, 27: {From: 0x87e, To: 0x810}, - 28: {From: 0x8c3, To: 0xee3}, - 29: {From: 0x9ef, To: 0x331}, - 30: {From: 0xa36, To: 0x2c5}, - 31: {From: 0xa3d, To: 0xbf}, - 32: {From: 0xabe, To: 0x3322}, - 33: {From: 0xb38, To: 0x529}, - 34: {From: 0xb75, To: 0x265a}, - 35: {From: 0xb7e, To: 0xbc3}, - 36: {From: 0xb9b, To: 0x44e}, - 37: {From: 0xbbc, To: 0x4229}, - 38: {From: 0xbbf, To: 0x529}, - 39: {From: 0xbfe, To: 0x2da7}, - 40: {From: 0xc2e, To: 0x3181}, - 41: {From: 0xcb9, To: 0xf3}, - 42: {From: 0xd08, To: 0xfa}, - 43: {From: 0xdc8, To: 0x11a}, - 44: {From: 0xdd7, To: 0x32d}, - 45: {From: 0xdf8, To: 0xdfb}, - 46: {From: 0xdfe, To: 0x531}, - 47: {From: 0xe01, To: 0xdf3}, - 48: {From: 0xedf, To: 0x205a}, - 49: {From: 0xee9, To: 0x222e}, - 50: {From: 0xeee, To: 0x2e9a}, - 51: {From: 0xf39, To: 0x367}, - 52: {From: 0x10d0, To: 0x140}, - 53: {From: 0x1104, To: 0x2d0}, - 54: {From: 0x11a0, To: 0x1ec}, - 55: {From: 0x1279, To: 0x21}, - 56: {From: 0x1424, To: 0x15e}, - 57: {From: 0x1470, To: 0x14e}, - 58: {From: 0x151f, To: 0xd9b}, - 59: {From: 0x1523, To: 0x390}, - 60: {From: 0x1532, To: 0x19f}, - 61: {From: 0x1580, To: 0x210}, - 62: {From: 0x1583, To: 0x10d}, - 63: {From: 0x15a3, To: 0x3caf}, - 64: {From: 0x1630, To: 0x222e}, - 65: {From: 0x166a, To: 0x19b}, - 66: {From: 0x16c8, To: 0x136}, - 67: {From: 0x1700, To: 0x29f8}, - 68: {From: 0x1718, To: 0x194}, - 69: {From: 0x1727, To: 0xf3f}, - 70: {From: 0x177a, To: 0x178}, - 71: {From: 0x1809, To: 0x17b6}, - 72: {From: 0x1816, To: 0x18f3}, - 73: {From: 0x188a, To: 0x436}, - 74: {From: 0x1979, To: 0x1d01}, - 75: {From: 0x1a74, To: 0x2bb0}, - 76: {From: 0x1a8a, To: 0x1f8}, - 77: {From: 0x1b5a, To: 0x1fa}, - 78: {From: 0x1b86, To: 0x1515}, - 79: {From: 0x1d64, To: 0x2c9b}, - 80: {From: 0x2038, To: 0x37b1}, - 81: {From: 0x203d, To: 0x20dd}, - 82: {From: 0x205a, To: 0x30b}, - 83: {From: 0x20e3, To: 0x274}, - 84: {From: 0x20ee, To: 0x263}, - 85: {From: 0x20f2, To: 0x22d}, - 86: {From: 0x20f9, To: 0x256}, - 87: {From: 0x210f, To: 0x21eb}, - 88: {From: 0x2135, To: 0x27d}, - 89: {From: 0x2160, To: 0x913}, - 90: {From: 0x2199, To: 0x121}, - 91: {From: 0x21ce, To: 0x1561}, - 92: {From: 0x21e6, To: 0x504}, - 93: {From: 0x21f4, To: 0x49f}, - 94: {From: 0x21fb, To: 0x269}, - 95: {From: 0x222d, To: 0x121}, - 96: {From: 0x2237, To: 0x121}, - 97: {From: 0x2262, To: 0x92a}, - 98: {From: 0x2316, To: 0x3226}, - 99: {From: 0x236a, To: 0x2835}, - 100: {From: 0x2382, To: 0x3365}, - 101: {From: 0x2472, To: 0x2c7}, - 102: {From: 0x24e4, To: 0x2ff}, - 103: {From: 0x24f0, To: 0x2fa}, - 104: {From: 0x24fa, To: 0x31f}, - 105: {From: 0x2550, To: 0xb5b}, - 106: {From: 0x25a9, To: 0xe2}, - 107: {From: 0x263e, To: 0x2d0}, - 108: {From: 0x26c9, To: 0x26b4}, - 109: {From: 0x26f9, To: 0x3c8}, - 110: {From: 0x2727, To: 0x3caf}, - 111: {From: 0x2755, To: 0x6a4}, - 112: {From: 0x2765, To: 0x26b4}, - 113: {From: 0x2789, To: 0x4358}, - 114: {From: 0x27c9, To: 0x2001}, - 115: {From: 0x28ea, To: 0x27b1}, - 116: {From: 0x28ef, To: 0x2837}, - 117: {From: 0x2914, To: 0x351}, - 118: {From: 0x2986, To: 0x2da7}, - 119: {From: 0x29f0, To: 0x96b}, - 120: {From: 0x2b1a, To: 0x38d}, - 121: {From: 0x2bfc, To: 0x395}, - 122: {From: 0x2c3f, To: 0x3caf}, - 123: {From: 0x2cfc, To: 0x3be}, - 124: {From: 0x2d13, To: 0x597}, - 125: {From: 0x2d47, To: 0x148}, - 126: {From: 0x2d48, To: 0x148}, - 127: {From: 0x2dff, To: 0x2f1}, - 128: {From: 0x2e08, To: 0x19cc}, - 129: {From: 0x2e1a, To: 0x2d95}, - 130: {From: 0x2e21, To: 0x292}, - 131: {From: 0x2e54, To: 0x7d}, - 132: {From: 0x2e65, To: 0x2282}, - 133: {From: 0x2ea0, To: 0x2e9b}, - 134: {From: 0x2eef, To: 0x2ed7}, - 135: {From: 0x3193, To: 0x3c4}, - 136: {From: 0x3366, To: 0x338e}, - 137: {From: 0x342a, To: 0x3dc}, - 138: {From: 0x34ee, To: 0x18d0}, - 139: {From: 0x35c8, To: 0x2c9b}, - 140: {From: 0x35e6, To: 0x412}, - 141: {From: 0x3658, To: 0x246}, - 142: {From: 0x3676, To: 0x3f4}, - 143: {From: 0x36fd, To: 0x445}, - 144: {From: 0x37c0, To: 0x121}, - 145: {From: 0x3816, To: 0x38f2}, - 146: {From: 0x382a, To: 0x2b48}, - 147: {From: 0x382b, To: 0x2c9b}, - 148: {From: 0x382f, To: 0xa9}, - 149: {From: 0x3832, To: 0x3228}, - 150: {From: 0x386c, To: 0x39a6}, - 151: {From: 0x3892, To: 0x3fc0}, - 152: {From: 0x38a5, To: 0x39d7}, - 153: {From: 0x38b4, To: 0x1fa4}, - 154: {From: 0x38b5, To: 0x2e9a}, - 155: {From: 0x395c, To: 0x47e}, - 156: {From: 0x3b4e, To: 0xd91}, - 157: {From: 0x3b78, To: 0x137}, - 158: {From: 0x3c99, To: 0x4bc}, - 159: {From: 0x3fbd, To: 0x100}, - 160: {From: 0x4208, To: 0xa91}, - 161: {From: 0x42be, To: 0x573}, - 162: {From: 0x42f9, To: 0x3f60}, - 163: {From: 0x4378, To: 0x25a}, - 164: {From: 0x43b8, To: 0xe6c}, - 165: {From: 0x43cd, To: 0x10f}, - 166: {From: 0x44af, To: 0x3322}, - 167: {From: 0x44e3, To: 0x512}, - 168: {From: 0x45ca, To: 0x2409}, - 169: {From: 0x45dd, To: 0x26dc}, - 170: {From: 0x4610, To: 0x48ae}, - 171: {From: 0x46ae, To: 0x46a0}, - 172: {From: 0x473e, To: 0x4745}, - 173: {From: 0x4817, To: 0x3503}, - 174: {From: 0x4916, To: 0x31f}, - 175: {From: 0x49a7, To: 0x523}, + 28: {From: 0x8a8, To: 0x8b7}, + 29: {From: 0x8c3, To: 0xee3}, + 30: {From: 0x8fa, To: 0x1dc}, + 31: {From: 0x9ef, To: 0x331}, + 32: {From: 0xa36, To: 0x2c5}, + 33: {From: 0xa3d, To: 0xbf}, + 34: {From: 0xabe, To: 0x3322}, + 35: {From: 0xb38, To: 0x529}, + 36: {From: 0xb75, To: 0x265a}, + 37: {From: 0xb7e, To: 0xbc3}, + 38: {From: 0xb9b, To: 0x44e}, + 39: {From: 0xbbc, To: 0x4229}, + 40: {From: 0xbbf, To: 0x529}, + 41: {From: 0xbfe, To: 0x2da7}, + 42: {From: 0xc2e, To: 0x3181}, + 43: {From: 0xcb9, To: 0xf3}, + 44: {From: 0xd08, To: 0xfa}, + 45: {From: 0xdc8, To: 0x11a}, + 46: {From: 0xdd7, To: 0x32d}, + 47: {From: 0xdf8, To: 0xdfb}, + 48: {From: 0xdfe, To: 0x531}, + 49: {From: 0xe01, To: 0xdf3}, + 50: {From: 0xedf, To: 0x205a}, + 51: {From: 0xee9, To: 0x222e}, + 52: {From: 0xeee, To: 0x2e9a}, + 53: {From: 0xf39, To: 0x367}, + 54: {From: 0x10d0, To: 0x140}, + 55: {From: 0x1104, To: 0x2d0}, + 56: {From: 0x11a0, To: 0x1ec}, + 57: {From: 0x1279, To: 0x21}, + 58: {From: 0x1424, To: 0x15e}, + 59: {From: 0x1470, To: 0x14e}, + 60: {From: 0x151f, To: 0xd9b}, + 61: {From: 0x1523, To: 0x390}, + 62: {From: 0x1532, To: 0x19f}, + 63: {From: 0x1580, To: 0x210}, + 64: {From: 0x1583, To: 0x10d}, + 65: {From: 0x15a3, To: 0x3caf}, + 66: {From: 0x1630, To: 0x222e}, + 67: {From: 0x166a, To: 0x19b}, + 68: {From: 0x16c8, To: 0x136}, + 69: {From: 0x1700, To: 0x29f8}, + 70: {From: 0x1718, To: 0x194}, + 71: {From: 0x1727, To: 0xf3f}, + 72: {From: 0x177a, To: 0x178}, + 73: {From: 0x1809, To: 0x17b6}, + 74: {From: 0x1816, To: 0x18f3}, + 75: {From: 0x188a, To: 0x436}, + 76: {From: 0x1979, To: 0x1d01}, + 77: {From: 0x1a74, To: 0x2bb0}, + 78: {From: 0x1a8a, To: 0x1f8}, + 79: {From: 0x1b5a, To: 0x1fa}, + 80: {From: 0x1b86, To: 0x1515}, + 81: {From: 0x1d64, To: 0x2c9b}, + 82: {From: 0x2038, To: 0x37b1}, + 83: {From: 0x203d, To: 0x20dd}, + 84: {From: 0x205a, To: 0x30b}, + 85: {From: 0x20e3, To: 0x274}, + 86: {From: 0x20ee, To: 0x263}, + 87: {From: 0x20f2, To: 0x22d}, + 88: {From: 0x20f9, To: 0x256}, + 89: {From: 0x210f, To: 0x21eb}, + 90: {From: 0x2135, To: 0x27d}, + 91: {From: 0x2160, To: 0x913}, + 92: {From: 0x2199, To: 0x121}, + 93: {From: 0x21ce, To: 0x1561}, + 94: {From: 0x21e6, To: 0x504}, + 95: {From: 0x21f4, To: 0x49f}, + 96: {From: 0x21fb, To: 0x269}, + 97: {From: 0x222d, To: 0x121}, + 98: {From: 0x2237, To: 0x121}, + 99: {From: 0x2262, To: 0x92a}, + 100: {From: 0x2316, To: 0x3226}, + 101: {From: 0x236a, To: 0x2835}, + 102: {From: 0x2382, To: 0x3365}, + 103: {From: 0x2472, To: 0x2c7}, + 104: {From: 0x24e4, To: 0x2ff}, + 105: {From: 0x24f0, To: 0x2fa}, + 106: {From: 0x24fa, To: 0x31f}, + 107: {From: 0x2550, To: 0xb5b}, + 108: {From: 0x25a9, To: 0xe2}, + 109: {From: 0x263e, To: 0x2d0}, + 110: {From: 0x26c9, To: 0x26b4}, + 111: {From: 0x26f9, To: 0x3c8}, + 112: {From: 0x2727, To: 0x3caf}, + 113: {From: 0x2755, To: 0x6a4}, + 114: {From: 0x2765, To: 0x26b4}, + 115: {From: 0x2789, To: 0x4358}, + 116: {From: 0x27c9, To: 0x2001}, + 117: {From: 0x28ea, To: 0x27b1}, + 118: {From: 0x28ef, To: 0x2837}, + 119: {From: 0x2914, To: 0x351}, + 120: {From: 0x2986, To: 0x2da7}, + 121: {From: 0x29f0, To: 0x96b}, + 122: {From: 0x2b1a, To: 0x38d}, + 123: {From: 0x2bfc, To: 0x395}, + 124: {From: 0x2c3f, To: 0x3caf}, + 125: {From: 0x2ce1, To: 0x2201}, + 126: {From: 0x2cfc, To: 0x3be}, + 127: {From: 0x2d13, To: 0x597}, + 128: {From: 0x2d47, To: 0x148}, + 129: {From: 0x2d48, To: 0x148}, + 130: {From: 0x2dff, To: 0x2f1}, + 131: {From: 0x2e08, To: 0x19cc}, + 132: {From: 0x2e1a, To: 0x2d95}, + 133: {From: 0x2e21, To: 0x292}, + 134: {From: 0x2e54, To: 0x7d}, + 135: {From: 0x2e65, To: 0x2282}, + 136: {From: 0x2ea0, To: 0x2e9b}, + 137: {From: 0x2eef, To: 0x2ed7}, + 138: {From: 0x3193, To: 0x3c4}, + 139: {From: 0x3366, To: 0x338e}, + 140: {From: 0x342a, To: 0x3dc}, + 141: {From: 0x34ee, To: 0x18d0}, + 142: {From: 0x35c8, To: 0x2c9b}, + 143: {From: 0x35e6, To: 0x412}, + 144: {From: 0x3658, To: 0x246}, + 145: {From: 0x3676, To: 0x3f4}, + 146: {From: 0x36fd, To: 0x445}, + 147: {From: 0x37c0, To: 0x121}, + 148: {From: 0x3816, To: 0x38f2}, + 149: {From: 0x382a, To: 0x2b48}, + 150: {From: 0x382b, To: 0x2c9b}, + 151: {From: 0x382f, To: 0xa9}, + 152: {From: 0x3832, To: 0x3228}, + 153: {From: 0x386c, To: 0x39a6}, + 154: {From: 0x3892, To: 0x3fc0}, + 155: {From: 0x38a5, To: 0x39d7}, + 156: {From: 0x38b4, To: 0x1fa4}, + 157: {From: 0x38b5, To: 0x2e9a}, + 158: {From: 0x395c, To: 0x47e}, + 159: {From: 0x3b4e, To: 0xd91}, + 160: {From: 0x3b78, To: 0x137}, + 161: {From: 0x3c99, To: 0x4bc}, + 162: {From: 0x3fbd, To: 0x100}, + 163: {From: 0x4208, To: 0xa91}, + 164: {From: 0x42be, To: 0x573}, + 165: {From: 0x42f9, To: 0x3f60}, + 166: {From: 0x4378, To: 0x25a}, + 167: {From: 0x43b8, To: 0xe6c}, + 168: {From: 0x43cd, To: 0x10f}, + 169: {From: 0x44af, To: 0x3322}, + 170: {From: 0x44e3, To: 0x512}, + 171: {From: 0x45ca, To: 0x2409}, + 172: {From: 0x45dd, To: 0x26dc}, + 173: {From: 0x4610, To: 0x48ae}, + 174: {From: 0x46ae, To: 0x46a0}, + 175: {From: 0x473e, To: 0x4745}, + 176: {From: 0x4817, To: 0x3503}, + 177: {From: 0x4916, To: 0x31f}, + 178: {From: 0x49a7, To: 0x523}, } -// Size: 176 bytes, 176 elements -var AliasTypes = [176]AliasType{ +// Size: 179 bytes, 179 elements +var AliasTypes = [179]AliasType{ // Entry 0 - 3F 1, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 1, 0, 0, 1, 2, - 1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 2, 1, 1, - 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 1, 1, 0, - 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, 2, 0, + 1, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 0, 0, 2, + 1, 1, 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 1, + 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 2, // Entry 40 - 7F - 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0, 2, 1, 0, 0, - 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 1, 2, 2, 2, 0, 1, 1, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 2, 1, 1, + 2, 0, 0, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 0, 2, 1, + 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 2, 0, 1, 1, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, // Entry 80 - BF - 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 2, 1, 1, 1, - 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, - 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, + 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 2, 0, 0, 2, + 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 1, + 0, 1, 2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, + 0, 1, 1, } const ( @@ -785,17 +790,17 @@ const ( _Hani = 57 _Hans = 59 _Hant = 60 - _Qaaa = 143 - _Qaai = 151 - _Qabx = 192 - _Zinh = 245 - _Zyyy = 250 - _Zzzz = 251 + _Qaaa = 147 + _Qaai = 155 + _Qabx = 196 + _Zinh = 252 + _Zyyy = 257 + _Zzzz = 258 ) // script is an alphabetically sorted list of ISO 15924 codes. The index // of the script in the string, divided by 4, is the internal scriptID. -const script tag.Index = "" + // Size: 1012 bytes +const script tag.Index = "" + // Size: 1040 bytes "----AdlmAfakAghbAhomArabAranArmiArmnAvstBaliBamuBassBatkBengBhksBlisBopo" + "BrahBraiBugiBuhdCakmCansCariChamCherChrsCirtCoptCpmnCprtCyrlCyrsDevaDiak" + "DogrDsrtDuplEgydEgyhEgypElbaElymEthiGeokGeorGlagGongGonmGothGranGrekGujr" + @@ -803,14 +808,14 @@ const script tag.Index = "" + // Size: 1012 bytes "JavaJpanJurcKaliKanaKharKhmrKhojKitlKitsKndaKoreKpelKthiLanaLaooLatfLatg" + "LatnLekeLepcLimbLinaLinbLisuLomaLyciLydiMahjMakaMandManiMarcMayaMedfMend" + "MercMeroMlymModiMongMoonMrooMteiMultMymrNandNarbNbatNewaNkdbNkgbNkooNshu" + - "OgamOlckOrkhOryaOsgeOsmaPalmPaucPermPhagPhliPhlpPhlvPhnxPiqdPlrdPrtiQaaa" + - "QaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaamQaanQaaoQaapQaaqQaarQaas" + - "QaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabeQabfQabgQabhQabiQabjQabk" + - "QablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabwQabxRjngRohgRoroRunrSamr" + - "SaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogdSogoSoraSoyoSundSyloSyrcSyre" + - "SyrjSyrnTagbTakrTaleTaluTamlTangTavtTeluTengTfngTglgThaaThaiTibtTirhToto" + - "UgarVaiiVispWaraWchoWoleXpeoXsuxYeziYiiiZanbZinhZmthZsyeZsymZxxxZyyyZzzz" + - "\xff\xff\xff\xff" + "OgamOlckOrkhOryaOsgeOsmaOugrPalmPaucPcunPelmPermPhagPhliPhlpPhlvPhnxPiqd" + + "PlrdPrtiPsinQaaaQaabQaacQaadQaaeQaafQaagQaahQaaiQaajQaakQaalQaamQaanQaao" + + "QaapQaaqQaarQaasQaatQaauQaavQaawQaaxQaayQaazQabaQabbQabcQabdQabeQabfQabg" + + "QabhQabiQabjQabkQablQabmQabnQaboQabpQabqQabrQabsQabtQabuQabvQabwQabxRanj" + + "RjngRohgRoroRunrSamrSaraSarbSaurSgnwShawShrdShuiSiddSindSinhSogdSogoSora" + + "SoyoSundSyloSyrcSyreSyrjSyrnTagbTakrTaleTaluTamlTangTavtTeluTengTfngTglg" + + "ThaaThaiTibtTirhTnsaTotoUgarVaiiVispVithWaraWchoWoleXpeoXsuxYeziYiiiZanb" + + "ZinhZmthZsyeZsymZxxxZyyyZzzz\xff\xff\xff\xff" // suppressScript is an index from langID to the dominant script for that language, // if it exists. If a script is given, it should be suppressed from the language tag. @@ -858,7 +863,7 @@ var suppressScript = [1330]uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe5, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, + 0xea, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x5a, 0x00, 0x5a, 0x00, // Entry 140 - 17F @@ -962,7 +967,7 @@ var suppressScript = [1330]uint8{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Entry 400 - 43F 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -972,10 +977,10 @@ var suppressScript = [1330]uint8{ // Entry 440 - 47F 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe1, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x2c, + 0x00, 0xe6, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5a, 0x00, // Entry 480 - 4BF @@ -1086,9 +1091,9 @@ var regionTypes = [358]uint8{ // regionISO holds a list of alphabetically sorted 2-letter ISO region codes. // Each 2-letter codes is followed by two bytes with the following meaning: -// - [A-Z}{2}: the first letter of the 2-letter code plus these two -// letters form the 3-letter ISO code. -// - 0, n: index into altRegionISO3. +// - [A-Z}{2}: the first letter of the 2-letter code plus these two +// letters form the 3-letter ISO code. +// - 0, n: index into altRegionISO3. const regionISO tag.Index = "" + // Size: 1308 bytes "AAAAACSCADNDAEREAFFGAGTGAIIAALLBAMRMANNTAOGOAQTAARRGASSMATUTAUUSAWBWAXLA" + "AZZEBAIHBBRBBDGDBEELBFFABGGRBHHRBIDIBJENBLLMBMMUBNRNBOOLBQESBRRABSHSBTTN" + @@ -1206,7 +1211,9 @@ var m49 = [358]int16{ // m49Index gives indexes into fromM49 based on the three most significant bits // of a 10-bit UN.M49 code. To search an UN.M49 code in fromM49, search in -// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]] +// +// fromM49[m49Index[msb39(code)]:m49Index[msb3(code)+1]] +// // for an entry where the first 7 bits match the 7 lsb of the UN.M49 code. // The region code is stored in the 9 lsb of the indexed value. // Size: 18 bytes, 9 elements @@ -1268,117 +1275,118 @@ var fromM49 = [333]uint16{ 0xc759, 0xc95a, 0xcb5b, 0xcd5c, 0xcf65, } -// Size: 1995 bytes +// Size: 2014 bytes var variantIndex = map[string]uint8{ "1606nict": 0x0, "1694acad": 0x1, "1901": 0x2, "1959acad": 0x3, - "1994": 0x60, + "1994": 0x61, "1996": 0x4, "abl1943": 0x5, "akuapem": 0x6, - "alalc97": 0x62, + "alalc97": 0x63, "aluku": 0x7, "ao1990": 0x8, "aranes": 0x9, "arevela": 0xa, "arevmda": 0xb, - "asante": 0xc, - "auvern": 0xd, - "baku1926": 0xe, - "balanka": 0xf, - "barla": 0x10, - "basiceng": 0x11, - "bauddha": 0x12, - "biscayan": 0x13, - "biske": 0x5b, - "bohoric": 0x14, - "boont": 0x15, - "bornholm": 0x16, - "cisaup": 0x17, - "colb1945": 0x18, - "cornu": 0x19, - "creiss": 0x1a, - "dajnko": 0x1b, - "ekavsk": 0x1c, - "emodeng": 0x1d, - "fonipa": 0x63, - "fonkirsh": 0x64, - "fonnapa": 0x65, - "fonupa": 0x66, - "fonxsamp": 0x67, - "gascon": 0x1e, - "grclass": 0x1f, - "grital": 0x20, - "grmistr": 0x21, - "hepburn": 0x22, - "heploc": 0x61, - "hognorsk": 0x23, - "hsistemo": 0x24, - "ijekavsk": 0x25, - "itihasa": 0x26, - "ivanchov": 0x27, - "jauer": 0x28, - "jyutping": 0x29, - "kkcor": 0x2a, - "kociewie": 0x2b, - "kscor": 0x2c, - "laukika": 0x2d, - "lemosin": 0x2e, - "lengadoc": 0x2f, - "lipaw": 0x5c, - "luna1918": 0x30, - "metelko": 0x31, - "monoton": 0x32, - "ndyuka": 0x33, - "nedis": 0x34, - "newfound": 0x35, - "nicard": 0x36, - "njiva": 0x5d, - "nulik": 0x37, - "osojs": 0x5e, - "oxendict": 0x38, - "pahawh2": 0x39, - "pahawh3": 0x3a, - "pahawh4": 0x3b, - "pamaka": 0x3c, - "peano": 0x3d, - "petr1708": 0x3e, - "pinyin": 0x3f, - "polyton": 0x40, - "provenc": 0x41, - "puter": 0x42, - "rigik": 0x43, - "rozaj": 0x44, - "rumgr": 0x45, - "scotland": 0x46, - "scouse": 0x47, - "simple": 0x68, - "solba": 0x5f, - "sotav": 0x48, - "spanglis": 0x49, - "surmiran": 0x4a, - "sursilv": 0x4b, - "sutsilv": 0x4c, - "tarask": 0x4d, - "tongyong": 0x4e, - "tunumiit": 0x4f, - "uccor": 0x50, - "ucrcor": 0x51, - "ulster": 0x52, - "unifon": 0x53, - "vaidika": 0x54, - "valencia": 0x55, - "vallader": 0x56, - "vecdruka": 0x57, - "vivaraup": 0x58, - "wadegile": 0x59, - "xsistemo": 0x5a, + "arkaika": 0xc, + "asante": 0xd, + "auvern": 0xe, + "baku1926": 0xf, + "balanka": 0x10, + "barla": 0x11, + "basiceng": 0x12, + "bauddha": 0x13, + "biscayan": 0x14, + "biske": 0x5c, + "bohoric": 0x15, + "boont": 0x16, + "bornholm": 0x17, + "cisaup": 0x18, + "colb1945": 0x19, + "cornu": 0x1a, + "creiss": 0x1b, + "dajnko": 0x1c, + "ekavsk": 0x1d, + "emodeng": 0x1e, + "fonipa": 0x64, + "fonkirsh": 0x65, + "fonnapa": 0x66, + "fonupa": 0x67, + "fonxsamp": 0x68, + "gascon": 0x1f, + "grclass": 0x20, + "grital": 0x21, + "grmistr": 0x22, + "hepburn": 0x23, + "heploc": 0x62, + "hognorsk": 0x24, + "hsistemo": 0x25, + "ijekavsk": 0x26, + "itihasa": 0x27, + "ivanchov": 0x28, + "jauer": 0x29, + "jyutping": 0x2a, + "kkcor": 0x2b, + "kociewie": 0x2c, + "kscor": 0x2d, + "laukika": 0x2e, + "lemosin": 0x2f, + "lengadoc": 0x30, + "lipaw": 0x5d, + "luna1918": 0x31, + "metelko": 0x32, + "monoton": 0x33, + "ndyuka": 0x34, + "nedis": 0x35, + "newfound": 0x36, + "nicard": 0x37, + "njiva": 0x5e, + "nulik": 0x38, + "osojs": 0x5f, + "oxendict": 0x39, + "pahawh2": 0x3a, + "pahawh3": 0x3b, + "pahawh4": 0x3c, + "pamaka": 0x3d, + "peano": 0x3e, + "petr1708": 0x3f, + "pinyin": 0x40, + "polyton": 0x41, + "provenc": 0x42, + "puter": 0x43, + "rigik": 0x44, + "rozaj": 0x45, + "rumgr": 0x46, + "scotland": 0x47, + "scouse": 0x48, + "simple": 0x69, + "solba": 0x60, + "sotav": 0x49, + "spanglis": 0x4a, + "surmiran": 0x4b, + "sursilv": 0x4c, + "sutsilv": 0x4d, + "tarask": 0x4e, + "tongyong": 0x4f, + "tunumiit": 0x50, + "uccor": 0x51, + "ucrcor": 0x52, + "ulster": 0x53, + "unifon": 0x54, + "vaidika": 0x55, + "valencia": 0x56, + "vallader": 0x57, + "vecdruka": 0x58, + "vivaraup": 0x59, + "wadegile": 0x5a, + "xsistemo": 0x5b, } // variantNumSpecialized is the number of specialized variants in variants. -const variantNumSpecialized = 98 +const variantNumSpecialized = 99 // nRegionGroups is the number of region groups. const nRegionGroups = 33 @@ -1390,8 +1398,8 @@ type likelyLangRegion struct { // likelyScript is a lookup table, indexed by scriptID, for the most likely // languages and regions given a script. -// Size: 1012 bytes, 253 elements -var likelyScript = [253]likelyLangRegion{ +// Size: 1040 bytes, 260 elements +var likelyScript = [260]likelyLangRegion{ 1: {lang: 0x14e, region: 0x84}, 3: {lang: 0x2a2, region: 0x106}, 4: {lang: 0x1f, region: 0x99}, @@ -1489,57 +1497,57 @@ var likelyScript = [253]likelyLangRegion{ 129: {lang: 0x395, region: 0x99}, 130: {lang: 0x399, region: 0x135}, 131: {lang: 0x429, region: 0x115}, - 132: {lang: 0x3b, region: 0x11c}, - 133: {lang: 0xfd, region: 0xc4}, - 134: {lang: 0x27d, region: 0x106}, - 135: {lang: 0x2c9, region: 0x53}, - 136: {lang: 0x39f, region: 0x9c}, - 137: {lang: 0x39f, region: 0x53}, - 139: {lang: 0x3ad, region: 0xb0}, - 141: {lang: 0x1c6, region: 0x53}, - 142: {lang: 0x4fd, region: 0x9c}, - 193: {lang: 0x3cb, region: 0x95}, - 196: {lang: 0x372, region: 0x10c}, - 197: {lang: 0x420, region: 0x97}, - 199: {lang: 0x4ff, region: 0x15e}, - 200: {lang: 0x3f0, region: 0x99}, - 201: {lang: 0x45, region: 0x135}, - 202: {lang: 0x139, region: 0x7b}, - 203: {lang: 0x3e9, region: 0x99}, - 205: {lang: 0x3e9, region: 0x99}, - 206: {lang: 0x3fa, region: 0x99}, - 207: {lang: 0x40c, region: 0xb3}, - 210: {lang: 0x433, region: 0x99}, - 211: {lang: 0xef, region: 0xc5}, - 212: {lang: 0x43e, region: 0x95}, - 213: {lang: 0x44d, region: 0x35}, - 214: {lang: 0x44e, region: 0x9b}, - 218: {lang: 0x45a, region: 0xe7}, - 219: {lang: 0x11a, region: 0x99}, - 220: {lang: 0x45e, region: 0x53}, - 221: {lang: 0x232, region: 0x53}, - 222: {lang: 0x450, region: 0x99}, - 223: {lang: 0x4a5, region: 0x53}, - 224: {lang: 0x9f, region: 0x13e}, - 225: {lang: 0x461, region: 0x99}, - 227: {lang: 0x528, region: 0xba}, - 228: {lang: 0x153, region: 0xe7}, - 229: {lang: 0x128, region: 0xcd}, - 230: {lang: 0x46b, region: 0x123}, - 231: {lang: 0xa9, region: 0x53}, - 232: {lang: 0x2ce, region: 0x99}, - 234: {lang: 0x4ad, region: 0x11c}, - 235: {lang: 0x4be, region: 0xb4}, - 237: {lang: 0x1ce, region: 0x99}, - 240: {lang: 0x3a9, region: 0x9c}, - 241: {lang: 0x22, region: 0x9b}, - 243: {lang: 0x1ea, region: 0x53}, - 244: {lang: 0xef, region: 0xc5}, + 133: {lang: 0x3b, region: 0x11c}, + 134: {lang: 0xfd, region: 0xc4}, + 137: {lang: 0x27d, region: 0x106}, + 138: {lang: 0x2c9, region: 0x53}, + 139: {lang: 0x39f, region: 0x9c}, + 140: {lang: 0x39f, region: 0x53}, + 142: {lang: 0x3ad, region: 0xb0}, + 144: {lang: 0x1c6, region: 0x53}, + 145: {lang: 0x4fd, region: 0x9c}, + 198: {lang: 0x3cb, region: 0x95}, + 201: {lang: 0x372, region: 0x10c}, + 202: {lang: 0x420, region: 0x97}, + 204: {lang: 0x4ff, region: 0x15e}, + 205: {lang: 0x3f0, region: 0x99}, + 206: {lang: 0x45, region: 0x135}, + 207: {lang: 0x139, region: 0x7b}, + 208: {lang: 0x3e9, region: 0x99}, + 210: {lang: 0x3e9, region: 0x99}, + 211: {lang: 0x3fa, region: 0x99}, + 212: {lang: 0x40c, region: 0xb3}, + 215: {lang: 0x433, region: 0x99}, + 216: {lang: 0xef, region: 0xc5}, + 217: {lang: 0x43e, region: 0x95}, + 218: {lang: 0x44d, region: 0x35}, + 219: {lang: 0x44e, region: 0x9b}, + 223: {lang: 0x45a, region: 0xe7}, + 224: {lang: 0x11a, region: 0x99}, + 225: {lang: 0x45e, region: 0x53}, + 226: {lang: 0x232, region: 0x53}, + 227: {lang: 0x450, region: 0x99}, + 228: {lang: 0x4a5, region: 0x53}, + 229: {lang: 0x9f, region: 0x13e}, + 230: {lang: 0x461, region: 0x99}, + 232: {lang: 0x528, region: 0xba}, + 233: {lang: 0x153, region: 0xe7}, + 234: {lang: 0x128, region: 0xcd}, + 235: {lang: 0x46b, region: 0x123}, + 236: {lang: 0xa9, region: 0x53}, + 237: {lang: 0x2ce, region: 0x99}, + 240: {lang: 0x4ad, region: 0x11c}, + 241: {lang: 0x4be, region: 0xb4}, + 244: {lang: 0x1ce, region: 0x99}, + 247: {lang: 0x3a9, region: 0x9c}, + 248: {lang: 0x22, region: 0x9b}, + 250: {lang: 0x1ea, region: 0x53}, + 251: {lang: 0xef, region: 0xc5}, } type likelyScriptRegion struct { region uint16 - script uint8 + script uint16 flags uint8 } @@ -1547,7 +1555,7 @@ type likelyScriptRegion struct { // scripts and regions given incomplete information. If more entries exist for a // given language, region and script are the index and size respectively // of the list in likelyLangList. -// Size: 5320 bytes, 1330 elements +// Size: 7980 bytes, 1330 elements var likelyLang = [1330]likelyScriptRegion{ 0: {region: 0x135, script: 0x5a, flags: 0x0}, 1: {region: 0x6f, script: 0x5a, flags: 0x0}, @@ -1583,7 +1591,7 @@ var likelyLang = [1330]likelyScriptRegion{ 31: {region: 0x99, script: 0x4, flags: 0x0}, 32: {region: 0x165, script: 0x5a, flags: 0x0}, 33: {region: 0x80, script: 0x5a, flags: 0x0}, - 34: {region: 0x9b, script: 0xf1, flags: 0x0}, + 34: {region: 0x9b, script: 0xf8, flags: 0x0}, 35: {region: 0x165, script: 0x5a, flags: 0x0}, 36: {region: 0x165, script: 0x5a, flags: 0x0}, 37: {region: 0x14d, script: 0x5a, flags: 0x0}, @@ -1616,7 +1624,7 @@ var likelyLang = [1330]likelyScriptRegion{ 66: {region: 0x6b, script: 0x5, flags: 0x0}, 67: {region: 0x99, script: 0xe, flags: 0x0}, 68: {region: 0x12f, script: 0x5a, flags: 0x0}, - 69: {region: 0x135, script: 0xc9, flags: 0x0}, + 69: {region: 0x135, script: 0xce, flags: 0x0}, 70: {region: 0x165, script: 0x5a, flags: 0x0}, 71: {region: 0x165, script: 0x5a, flags: 0x0}, 72: {region: 0x6e, script: 0x5a, flags: 0x0}, @@ -1670,7 +1678,7 @@ var likelyLang = [1330]likelyScriptRegion{ 120: {region: 0x165, script: 0x5a, flags: 0x0}, 121: {region: 0x12f, script: 0x5a, flags: 0x0}, 122: {region: 0x52, script: 0x5a, flags: 0x0}, - 123: {region: 0x99, script: 0xde, flags: 0x0}, + 123: {region: 0x99, script: 0xe3, flags: 0x0}, 124: {region: 0xe8, script: 0x5, flags: 0x0}, 125: {region: 0x99, script: 0x22, flags: 0x0}, 126: {region: 0x38, script: 0x20, flags: 0x0}, @@ -1705,7 +1713,7 @@ var likelyLang = [1330]likelyScriptRegion{ 156: {region: 0x165, script: 0x5a, flags: 0x0}, 157: {region: 0xe7, script: 0x5a, flags: 0x0}, 158: {region: 0x165, script: 0x5a, flags: 0x0}, - 159: {region: 0x13e, script: 0xe0, flags: 0x0}, + 159: {region: 0x13e, script: 0xe5, flags: 0x0}, 160: {region: 0xc3, script: 0x5a, flags: 0x0}, 161: {region: 0x165, script: 0x5a, flags: 0x0}, 162: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -1715,7 +1723,7 @@ var likelyLang = [1330]likelyScriptRegion{ 166: {region: 0x165, script: 0x5a, flags: 0x0}, 167: {region: 0x165, script: 0x5a, flags: 0x0}, 168: {region: 0x165, script: 0x5a, flags: 0x0}, - 169: {region: 0x53, script: 0xe7, flags: 0x0}, + 169: {region: 0x53, script: 0xec, flags: 0x0}, 170: {region: 0x165, script: 0x5a, flags: 0x0}, 171: {region: 0x165, script: 0x5a, flags: 0x0}, 172: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -1785,7 +1793,7 @@ var likelyLang = [1330]likelyScriptRegion{ 236: {region: 0x165, script: 0x5a, flags: 0x0}, 237: {region: 0x165, script: 0x5a, flags: 0x0}, 238: {region: 0x165, script: 0x5a, flags: 0x0}, - 239: {region: 0xc5, script: 0xd3, flags: 0x0}, + 239: {region: 0xc5, script: 0xd8, flags: 0x0}, 240: {region: 0x78, script: 0x5a, flags: 0x0}, 241: {region: 0x6b, script: 0x1d, flags: 0x0}, 242: {region: 0xe7, script: 0x5a, flags: 0x0}, @@ -1799,7 +1807,7 @@ var likelyLang = [1330]likelyScriptRegion{ 250: {region: 0x5e, script: 0x5a, flags: 0x0}, 251: {region: 0xe9, script: 0x5a, flags: 0x0}, 252: {region: 0x49, script: 0x17, flags: 0x0}, - 253: {region: 0xc4, script: 0x85, flags: 0x0}, + 253: {region: 0xc4, script: 0x86, flags: 0x0}, 254: {region: 0x8, script: 0x2, flags: 0x1}, 255: {region: 0x106, script: 0x20, flags: 0x0}, 256: {region: 0x7b, script: 0x5a, flags: 0x0}, @@ -1842,12 +1850,12 @@ var likelyLang = [1330]likelyScriptRegion{ 293: {region: 0x165, script: 0x5a, flags: 0x0}, 294: {region: 0x165, script: 0x5a, flags: 0x0}, 295: {region: 0x165, script: 0x5a, flags: 0x0}, - 296: {region: 0xcd, script: 0xe5, flags: 0x0}, + 296: {region: 0xcd, script: 0xea, flags: 0x0}, 297: {region: 0x165, script: 0x5a, flags: 0x0}, 298: {region: 0x165, script: 0x5a, flags: 0x0}, 299: {region: 0x114, script: 0x5a, flags: 0x0}, 300: {region: 0x37, script: 0x5a, flags: 0x0}, - 301: {region: 0x43, script: 0xe7, flags: 0x0}, + 301: {region: 0x43, script: 0xec, flags: 0x0}, 302: {region: 0x165, script: 0x5a, flags: 0x0}, 303: {region: 0xa4, script: 0x5a, flags: 0x0}, 304: {region: 0x80, script: 0x5a, flags: 0x0}, @@ -1957,7 +1965,7 @@ var likelyLang = [1330]likelyScriptRegion{ 408: {region: 0x165, script: 0x2c, flags: 0x0}, 409: {region: 0x165, script: 0x5a, flags: 0x0}, 410: {region: 0x99, script: 0x22, flags: 0x0}, - 411: {region: 0x99, script: 0xe1, flags: 0x0}, + 411: {region: 0x99, script: 0xe6, flags: 0x0}, 412: {region: 0x95, script: 0x5a, flags: 0x0}, 413: {region: 0xd9, script: 0x5a, flags: 0x0}, 414: {region: 0x130, script: 0x32, flags: 0x0}, @@ -2000,7 +2008,7 @@ var likelyLang = [1330]likelyScriptRegion{ 451: {region: 0xe7, script: 0x5a, flags: 0x0}, 452: {region: 0x165, script: 0x5a, flags: 0x0}, 453: {region: 0x12b, script: 0x40, flags: 0x0}, - 454: {region: 0x53, script: 0x8d, flags: 0x0}, + 454: {region: 0x53, script: 0x90, flags: 0x0}, 455: {region: 0x165, script: 0x5a, flags: 0x0}, 456: {region: 0xe8, script: 0x5, flags: 0x0}, 457: {region: 0x99, script: 0x22, flags: 0x0}, @@ -2035,7 +2043,7 @@ var likelyLang = [1330]likelyScriptRegion{ 487: {region: 0xd6, script: 0x5a, flags: 0x0}, 488: {region: 0x165, script: 0x5a, flags: 0x0}, 489: {region: 0x165, script: 0x5a, flags: 0x0}, - 490: {region: 0x53, script: 0xf3, flags: 0x0}, + 490: {region: 0x53, script: 0xfa, flags: 0x0}, 491: {region: 0x165, script: 0x5a, flags: 0x0}, 492: {region: 0x135, script: 0x5a, flags: 0x0}, 493: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2095,7 +2103,7 @@ var likelyLang = [1330]likelyScriptRegion{ 547: {region: 0x12f, script: 0x5a, flags: 0x0}, 548: {region: 0x122, script: 0x5, flags: 0x0}, 549: {region: 0x165, script: 0x5a, flags: 0x0}, - 550: {region: 0x123, script: 0xe6, flags: 0x0}, + 550: {region: 0x123, script: 0xeb, flags: 0x0}, 551: {region: 0x5a, script: 0x5a, flags: 0x0}, 552: {region: 0x52, script: 0x5a, flags: 0x0}, 553: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2107,7 +2115,7 @@ var likelyLang = [1330]likelyScriptRegion{ 559: {region: 0x165, script: 0x5a, flags: 0x0}, 560: {region: 0x41, script: 0x5a, flags: 0x0}, 561: {region: 0x99, script: 0x5a, flags: 0x0}, - 562: {region: 0x53, script: 0xdd, flags: 0x0}, + 562: {region: 0x53, script: 0xe2, flags: 0x0}, 563: {region: 0x99, script: 0x22, flags: 0x0}, 564: {region: 0xc3, script: 0x5a, flags: 0x0}, 565: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2191,7 +2199,7 @@ var likelyLang = [1330]likelyScriptRegion{ 643: {region: 0x165, script: 0x5a, flags: 0x0}, 644: {region: 0x165, script: 0x5a, flags: 0x0}, 645: {region: 0x165, script: 0x2c, flags: 0x0}, - 646: {region: 0x123, script: 0xe6, flags: 0x0}, + 646: {region: 0x123, script: 0xeb, flags: 0x0}, 647: {region: 0xe8, script: 0x5, flags: 0x0}, 648: {region: 0x165, script: 0x5a, flags: 0x0}, 649: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2211,7 +2219,7 @@ var likelyLang = [1330]likelyScriptRegion{ 663: {region: 0x165, script: 0x5a, flags: 0x0}, 664: {region: 0x95, script: 0x5a, flags: 0x0}, 665: {region: 0x165, script: 0x5a, flags: 0x0}, - 666: {region: 0x53, script: 0xe6, flags: 0x0}, + 666: {region: 0x53, script: 0xeb, flags: 0x0}, 667: {region: 0x165, script: 0x5a, flags: 0x0}, 668: {region: 0x165, script: 0x5a, flags: 0x0}, 669: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2235,7 +2243,7 @@ var likelyLang = [1330]likelyScriptRegion{ 687: {region: 0x135, script: 0x5a, flags: 0x0}, 688: {region: 0x165, script: 0x5a, flags: 0x0}, 689: {region: 0x165, script: 0x5a, flags: 0x0}, - 690: {region: 0x99, script: 0xe1, flags: 0x0}, + 690: {region: 0x99, script: 0xe6, flags: 0x0}, 691: {region: 0x9e, script: 0x5a, flags: 0x0}, 692: {region: 0x165, script: 0x5a, flags: 0x0}, 693: {region: 0x4b, script: 0x5a, flags: 0x0}, @@ -2257,7 +2265,7 @@ var likelyLang = [1330]likelyScriptRegion{ 709: {region: 0xa4, script: 0x5a, flags: 0x0}, 710: {region: 0x9c, script: 0x5, flags: 0x0}, 711: {region: 0xb8, script: 0x5a, flags: 0x0}, - 712: {region: 0x123, script: 0xe6, flags: 0x0}, + 712: {region: 0x123, script: 0xeb, flags: 0x0}, 713: {region: 0x53, script: 0x3b, flags: 0x0}, 714: {region: 0x12b, script: 0x5a, flags: 0x0}, 715: {region: 0x95, script: 0x5a, flags: 0x0}, @@ -2424,7 +2432,7 @@ var likelyLang = [1330]likelyScriptRegion{ 879: {region: 0xda, script: 0x5a, flags: 0x0}, 880: {region: 0x123, script: 0x56, flags: 0x0}, 881: {region: 0x99, script: 0x22, flags: 0x0}, - 882: {region: 0x10c, script: 0xc4, flags: 0x0}, + 882: {region: 0x10c, script: 0xc9, flags: 0x0}, 883: {region: 0x165, script: 0x5a, flags: 0x0}, 884: {region: 0x165, script: 0x5a, flags: 0x0}, 885: {region: 0x84, script: 0x7c, flags: 0x0}, @@ -2478,11 +2486,11 @@ var likelyLang = [1330]likelyScriptRegion{ 934: {region: 0x135, script: 0x5a, flags: 0x0}, 935: {region: 0x49, script: 0x5a, flags: 0x0}, 936: {region: 0x165, script: 0x5a, flags: 0x0}, - 937: {region: 0x9c, script: 0xf0, flags: 0x0}, + 937: {region: 0x9c, script: 0xf7, flags: 0x0}, 938: {region: 0x165, script: 0x5a, flags: 0x0}, 939: {region: 0x60, script: 0x5a, flags: 0x0}, 940: {region: 0x165, script: 0x5, flags: 0x0}, - 941: {region: 0xb0, script: 0x8b, flags: 0x0}, + 941: {region: 0xb0, script: 0x8e, flags: 0x0}, 943: {region: 0x165, script: 0x5a, flags: 0x0}, 944: {region: 0x165, script: 0x5a, flags: 0x0}, 945: {region: 0x99, script: 0x12, flags: 0x0}, @@ -2548,7 +2556,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1005: {region: 0x95, script: 0x5a, flags: 0x0}, 1006: {region: 0x99, script: 0x5a, flags: 0x0}, 1007: {region: 0x114, script: 0x5a, flags: 0x0}, - 1008: {region: 0x99, script: 0xc8, flags: 0x0}, + 1008: {region: 0x99, script: 0xcd, flags: 0x0}, 1009: {region: 0x165, script: 0x5a, flags: 0x0}, 1010: {region: 0x165, script: 0x5a, flags: 0x0}, 1011: {region: 0x12f, script: 0x5a, flags: 0x0}, @@ -2571,11 +2579,11 @@ var likelyLang = [1330]likelyScriptRegion{ 1028: {region: 0xb6, script: 0x5a, flags: 0x0}, 1029: {region: 0x165, script: 0x2c, flags: 0x0}, 1030: {region: 0x165, script: 0x5a, flags: 0x0}, - 1032: {region: 0xba, script: 0xe3, flags: 0x0}, + 1032: {region: 0xba, script: 0xe8, flags: 0x0}, 1033: {region: 0x165, script: 0x5a, flags: 0x0}, 1034: {region: 0xc4, script: 0x75, flags: 0x0}, 1035: {region: 0x165, script: 0x5, flags: 0x0}, - 1036: {region: 0xb3, script: 0xcf, flags: 0x0}, + 1036: {region: 0xb3, script: 0xd4, flags: 0x0}, 1037: {region: 0x6f, script: 0x5a, flags: 0x0}, 1038: {region: 0x165, script: 0x5a, flags: 0x0}, 1039: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2594,7 +2602,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1052: {region: 0x10c, script: 0x5a, flags: 0x0}, 1054: {region: 0x10c, script: 0x5a, flags: 0x0}, 1055: {region: 0x72, script: 0x5a, flags: 0x0}, - 1056: {region: 0x97, script: 0xc5, flags: 0x0}, + 1056: {region: 0x97, script: 0xca, flags: 0x0}, 1057: {region: 0x165, script: 0x5a, flags: 0x0}, 1058: {region: 0x72, script: 0x5a, flags: 0x0}, 1059: {region: 0x164, script: 0x5a, flags: 0x0}, @@ -2606,14 +2614,14 @@ var likelyLang = [1330]likelyScriptRegion{ 1065: {region: 0x115, script: 0x5a, flags: 0x0}, 1066: {region: 0x165, script: 0x5a, flags: 0x0}, 1067: {region: 0x165, script: 0x5a, flags: 0x0}, - 1068: {region: 0x123, script: 0xe6, flags: 0x0}, + 1068: {region: 0x123, script: 0xeb, flags: 0x0}, 1069: {region: 0x165, script: 0x5a, flags: 0x0}, 1070: {region: 0x165, script: 0x5a, flags: 0x0}, 1071: {region: 0x165, script: 0x5a, flags: 0x0}, 1072: {region: 0x165, script: 0x5a, flags: 0x0}, 1073: {region: 0x27, script: 0x5a, flags: 0x0}, 1074: {region: 0x37, script: 0x5, flags: 0x1}, - 1075: {region: 0x99, script: 0xd2, flags: 0x0}, + 1075: {region: 0x99, script: 0xd7, flags: 0x0}, 1076: {region: 0x116, script: 0x5a, flags: 0x0}, 1077: {region: 0x114, script: 0x5a, flags: 0x0}, 1078: {region: 0x99, script: 0x22, flags: 0x0}, @@ -2640,9 +2648,9 @@ var likelyLang = [1330]likelyScriptRegion{ 1099: {region: 0x95, script: 0x5a, flags: 0x0}, 1100: {region: 0x165, script: 0x5a, flags: 0x0}, 1101: {region: 0x35, script: 0xe, flags: 0x0}, - 1102: {region: 0x9b, script: 0xd6, flags: 0x0}, + 1102: {region: 0x9b, script: 0xdb, flags: 0x0}, 1103: {region: 0xe9, script: 0x5a, flags: 0x0}, - 1104: {region: 0x99, script: 0xde, flags: 0x0}, + 1104: {region: 0x99, script: 0xe3, flags: 0x0}, 1105: {region: 0xdb, script: 0x22, flags: 0x0}, 1106: {region: 0x165, script: 0x5a, flags: 0x0}, 1107: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2656,10 +2664,10 @@ var likelyLang = [1330]likelyScriptRegion{ 1115: {region: 0x165, script: 0x5a, flags: 0x0}, 1116: {region: 0x165, script: 0x5a, flags: 0x0}, 1117: {region: 0x99, script: 0x52, flags: 0x0}, - 1118: {region: 0x53, script: 0xdc, flags: 0x0}, + 1118: {region: 0x53, script: 0xe1, flags: 0x0}, 1119: {region: 0xdb, script: 0x22, flags: 0x0}, 1120: {region: 0xdb, script: 0x22, flags: 0x0}, - 1121: {region: 0x99, script: 0xe1, flags: 0x0}, + 1121: {region: 0x99, script: 0xe6, flags: 0x0}, 1122: {region: 0x165, script: 0x5a, flags: 0x0}, 1123: {region: 0x112, script: 0x5a, flags: 0x0}, 1124: {region: 0x131, script: 0x5a, flags: 0x0}, @@ -2669,7 +2677,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1128: {region: 0x165, script: 0x5a, flags: 0x0}, 1129: {region: 0x165, script: 0x5a, flags: 0x0}, 1130: {region: 0x165, script: 0x5a, flags: 0x0}, - 1131: {region: 0x123, script: 0xe6, flags: 0x0}, + 1131: {region: 0x123, script: 0xeb, flags: 0x0}, 1132: {region: 0xdb, script: 0x22, flags: 0x0}, 1133: {region: 0xdb, script: 0x22, flags: 0x0}, 1134: {region: 0xdb, script: 0x22, flags: 0x0}, @@ -2708,14 +2716,14 @@ var likelyLang = [1330]likelyScriptRegion{ 1167: {region: 0x87, script: 0x34, flags: 0x0}, 1168: {region: 0xdb, script: 0x22, flags: 0x0}, 1169: {region: 0xe7, script: 0x5a, flags: 0x0}, - 1170: {region: 0x43, script: 0xe7, flags: 0x0}, + 1170: {region: 0x43, script: 0xec, flags: 0x0}, 1171: {region: 0x165, script: 0x5a, flags: 0x0}, 1172: {region: 0x106, script: 0x20, flags: 0x0}, 1173: {region: 0x165, script: 0x5a, flags: 0x0}, 1174: {region: 0x165, script: 0x5a, flags: 0x0}, 1175: {region: 0x131, script: 0x5a, flags: 0x0}, 1176: {region: 0x165, script: 0x5a, flags: 0x0}, - 1177: {region: 0x123, script: 0xe6, flags: 0x0}, + 1177: {region: 0x123, script: 0xeb, flags: 0x0}, 1178: {region: 0x32, script: 0x5a, flags: 0x0}, 1179: {region: 0x165, script: 0x5a, flags: 0x0}, 1180: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2726,7 +2734,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1185: {region: 0x165, script: 0x5a, flags: 0x0}, 1187: {region: 0x165, script: 0x5a, flags: 0x0}, 1188: {region: 0xd4, script: 0x5a, flags: 0x0}, - 1189: {region: 0x53, script: 0xdf, flags: 0x0}, + 1189: {region: 0x53, script: 0xe4, flags: 0x0}, 1190: {region: 0xe5, script: 0x5a, flags: 0x0}, 1191: {region: 0x165, script: 0x5a, flags: 0x0}, 1192: {region: 0x106, script: 0x20, flags: 0x0}, @@ -2734,7 +2742,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1194: {region: 0x165, script: 0x5a, flags: 0x0}, 1195: {region: 0x106, script: 0x20, flags: 0x0}, 1196: {region: 0x3f, script: 0x4, flags: 0x1}, - 1197: {region: 0x11c, script: 0xea, flags: 0x0}, + 1197: {region: 0x11c, script: 0xf0, flags: 0x0}, 1198: {region: 0x130, script: 0x20, flags: 0x0}, 1199: {region: 0x75, script: 0x5a, flags: 0x0}, 1200: {region: 0x2a, script: 0x5a, flags: 0x0}, @@ -2750,7 +2758,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1211: {region: 0x165, script: 0x5a, flags: 0x0}, 1212: {region: 0x46, script: 0x4, flags: 0x1}, 1213: {region: 0x165, script: 0x5a, flags: 0x0}, - 1214: {region: 0xb4, script: 0xeb, flags: 0x0}, + 1214: {region: 0xb4, script: 0xf1, flags: 0x0}, 1215: {region: 0x165, script: 0x5a, flags: 0x0}, 1216: {region: 0x161, script: 0x5a, flags: 0x0}, 1217: {region: 0x9e, script: 0x5a, flags: 0x0}, @@ -2773,7 +2781,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1234: {region: 0x165, script: 0x5a, flags: 0x0}, 1235: {region: 0xe7, script: 0x5a, flags: 0x0}, 1236: {region: 0x2f, script: 0x5a, flags: 0x0}, - 1237: {region: 0x99, script: 0xe1, flags: 0x0}, + 1237: {region: 0x99, script: 0xe6, flags: 0x0}, 1238: {region: 0x99, script: 0x22, flags: 0x0}, 1239: {region: 0x165, script: 0x5a, flags: 0x0}, 1240: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2813,9 +2821,9 @@ var likelyLang = [1330]likelyScriptRegion{ 1274: {region: 0x99, script: 0x22, flags: 0x0}, 1275: {region: 0x131, script: 0x5a, flags: 0x0}, 1276: {region: 0x165, script: 0x5a, flags: 0x0}, - 1277: {region: 0x9c, script: 0x8e, flags: 0x0}, + 1277: {region: 0x9c, script: 0x91, flags: 0x0}, 1278: {region: 0x165, script: 0x5a, flags: 0x0}, - 1279: {region: 0x15e, script: 0xc7, flags: 0x0}, + 1279: {region: 0x15e, script: 0xcc, flags: 0x0}, 1280: {region: 0x165, script: 0x5a, flags: 0x0}, 1281: {region: 0x165, script: 0x5a, flags: 0x0}, 1282: {region: 0xdb, script: 0x22, flags: 0x0}, @@ -2855,7 +2863,7 @@ var likelyLang = [1330]likelyScriptRegion{ 1316: {region: 0x10b, script: 0x5a, flags: 0x0}, 1318: {region: 0xa8, script: 0x5, flags: 0x0}, 1319: {region: 0xd9, script: 0x5a, flags: 0x0}, - 1320: {region: 0xba, script: 0xe3, flags: 0x0}, + 1320: {region: 0xba, script: 0xe8, flags: 0x0}, 1321: {region: 0x4d, script: 0x14, flags: 0x1}, 1322: {region: 0x53, script: 0x7d, flags: 0x0}, 1323: {region: 0x165, script: 0x5a, flags: 0x0}, @@ -2867,11 +2875,11 @@ var likelyLang = [1330]likelyScriptRegion{ } // likelyLangList holds lists info associated with likelyLang. -// Size: 388 bytes, 97 elements +// Size: 582 bytes, 97 elements var likelyLangList = [97]likelyScriptRegion{ 0: {region: 0x9c, script: 0x7, flags: 0x0}, 1: {region: 0xa1, script: 0x78, flags: 0x2}, - 2: {region: 0x11c, script: 0x84, flags: 0x2}, + 2: {region: 0x11c, script: 0x85, flags: 0x2}, 3: {region: 0x32, script: 0x5a, flags: 0x0}, 4: {region: 0x9b, script: 0x5, flags: 0x4}, 5: {region: 0x9c, script: 0x5, flags: 0x4}, @@ -2880,7 +2888,7 @@ var likelyLangList = [97]likelyScriptRegion{ 8: {region: 0x106, script: 0x20, flags: 0x0}, 9: {region: 0x38, script: 0x2f, flags: 0x2}, 10: {region: 0x135, script: 0x5a, flags: 0x0}, - 11: {region: 0x7b, script: 0xca, flags: 0x2}, + 11: {region: 0x7b, script: 0xcf, flags: 0x2}, 12: {region: 0x114, script: 0x5a, flags: 0x0}, 13: {region: 0x84, script: 0x1, flags: 0x2}, 14: {region: 0x5d, script: 0x1f, flags: 0x0}, @@ -2916,14 +2924,14 @@ var likelyLangList = [97]likelyScriptRegion{ 44: {region: 0x99, script: 0x36, flags: 0x0}, 45: {region: 0xe8, script: 0x5, flags: 0x4}, 46: {region: 0xe8, script: 0x5, flags: 0x2}, - 47: {region: 0x9c, script: 0x88, flags: 0x0}, - 48: {region: 0x53, script: 0x89, flags: 0x2}, - 49: {region: 0xba, script: 0xe3, flags: 0x0}, + 47: {region: 0x9c, script: 0x8b, flags: 0x0}, + 48: {region: 0x53, script: 0x8c, flags: 0x2}, + 49: {region: 0xba, script: 0xe8, flags: 0x0}, 50: {region: 0xd9, script: 0x5a, flags: 0x4}, 51: {region: 0xe8, script: 0x5, flags: 0x0}, 52: {region: 0x99, script: 0x22, flags: 0x2}, 53: {region: 0x99, script: 0x4f, flags: 0x2}, - 54: {region: 0x99, script: 0xce, flags: 0x2}, + 54: {region: 0x99, script: 0xd3, flags: 0x2}, 55: {region: 0x105, script: 0x20, flags: 0x0}, 56: {region: 0xbd, script: 0x5a, flags: 0x4}, 57: {region: 0x104, script: 0x5a, flags: 0x4}, @@ -2970,7 +2978,7 @@ var likelyLangList = [97]likelyScriptRegion{ type likelyLangScript struct { lang uint16 - script uint8 + script uint16 flags uint8 } @@ -2979,7 +2987,7 @@ type likelyLangScript struct { // for a given regionID, lang and script are the index and size respectively // of the list in likelyRegionList. // TODO: exclude containers and user-definable regions from the list. -// Size: 1432 bytes, 358 elements +// Size: 2148 bytes, 358 elements var likelyRegion = [358]likelyLangScript{ 34: {lang: 0xd7, script: 0x5a, flags: 0x0}, 35: {lang: 0x3a, script: 0x5, flags: 0x0}, @@ -3086,7 +3094,7 @@ var likelyRegion = [358]likelyLangScript{ 175: {lang: 0x27, script: 0x2, flags: 0x1}, 176: {lang: 0x3a, script: 0x5, flags: 0x0}, 178: {lang: 0x10d, script: 0x5a, flags: 0x0}, - 179: {lang: 0x40c, script: 0xcf, flags: 0x0}, + 179: {lang: 0x40c, script: 0xd4, flags: 0x0}, 181: {lang: 0x43b, script: 0x5a, flags: 0x0}, 182: {lang: 0x2c0, script: 0x5a, flags: 0x0}, 183: {lang: 0x15e, script: 0x5a, flags: 0x0}, @@ -3107,7 +3115,7 @@ var likelyRegion = [358]likelyLangScript{ 201: {lang: 0x35, script: 0x2, flags: 0x1}, 203: {lang: 0x320, script: 0x5a, flags: 0x0}, 204: {lang: 0x37, script: 0x3, flags: 0x1}, - 205: {lang: 0x128, script: 0xe5, flags: 0x0}, + 205: {lang: 0x128, script: 0xea, flags: 0x0}, 207: {lang: 0x13e, script: 0x5a, flags: 0x0}, 208: {lang: 0x31f, script: 0x5a, flags: 0x0}, 209: {lang: 0x3c0, script: 0x5a, flags: 0x0}, @@ -3185,7 +3193,7 @@ var likelyRegion = [358]likelyLangScript{ } // likelyRegionList holds lists info associated with likelyRegion. -// Size: 372 bytes, 93 elements +// Size: 558 bytes, 93 elements var likelyRegionList = [93]likelyLangScript{ 0: {lang: 0x148, script: 0x5, flags: 0x0}, 1: {lang: 0x476, script: 0x5a, flags: 0x0}, @@ -3195,12 +3203,12 @@ var likelyRegionList = [93]likelyLangScript{ 5: {lang: 0x274, script: 0x5a, flags: 0x0}, 6: {lang: 0xb7, script: 0x5a, flags: 0x0}, 7: {lang: 0x432, script: 0x20, flags: 0x0}, - 8: {lang: 0x12d, script: 0xe7, flags: 0x0}, + 8: {lang: 0x12d, script: 0xec, flags: 0x0}, 9: {lang: 0x351, script: 0x22, flags: 0x0}, 10: {lang: 0x529, script: 0x3b, flags: 0x0}, 11: {lang: 0x4ac, script: 0x5, flags: 0x0}, 12: {lang: 0x523, script: 0x5a, flags: 0x0}, - 13: {lang: 0x29a, script: 0xe6, flags: 0x0}, + 13: {lang: 0x29a, script: 0xeb, flags: 0x0}, 14: {lang: 0x136, script: 0x34, flags: 0x0}, 15: {lang: 0x48a, script: 0x5a, flags: 0x0}, 16: {lang: 0x3a, script: 0x5, flags: 0x0}, @@ -3223,11 +3231,11 @@ var likelyRegionList = [93]likelyLangScript{ 33: {lang: 0x476, script: 0x5a, flags: 0x0}, 34: {lang: 0x24a, script: 0x4e, flags: 0x0}, 35: {lang: 0xe6, script: 0x5, flags: 0x0}, - 36: {lang: 0x226, script: 0xe6, flags: 0x0}, + 36: {lang: 0x226, script: 0xeb, flags: 0x0}, 37: {lang: 0x3a, script: 0x5, flags: 0x0}, 38: {lang: 0x15e, script: 0x5a, flags: 0x0}, 39: {lang: 0x2b8, script: 0x57, flags: 0x0}, - 40: {lang: 0x226, script: 0xe6, flags: 0x0}, + 40: {lang: 0x226, script: 0xeb, flags: 0x0}, 41: {lang: 0x3a, script: 0x5, flags: 0x0}, 42: {lang: 0x15e, script: 0x5a, flags: 0x0}, 43: {lang: 0x3dc, script: 0x5a, flags: 0x0}, @@ -3260,7 +3268,7 @@ var likelyRegionList = [93]likelyLangScript{ 70: {lang: 0x15e, script: 0x5a, flags: 0x0}, 71: {lang: 0x15e, script: 0x5a, flags: 0x0}, 72: {lang: 0x35, script: 0x5, flags: 0x0}, - 73: {lang: 0x46b, script: 0xe6, flags: 0x0}, + 73: {lang: 0x46b, script: 0xeb, flags: 0x0}, 74: {lang: 0x2ec, script: 0x5, flags: 0x0}, 75: {lang: 0x30f, script: 0x75, flags: 0x0}, 76: {lang: 0x467, script: 0x20, flags: 0x0}, @@ -3285,7 +3293,7 @@ var likelyRegionList = [93]likelyLangScript{ type likelyTag struct { lang uint16 region uint16 - script uint8 + script uint16 } // Size: 198 bytes, 33 elements @@ -3446,8 +3454,8 @@ var regionInclusionNext = [73]uint8{ type parentRel struct { lang uint16 - script uint8 - maxScript uint8 + script uint16 + maxScript uint16 toRegion uint16 fromRegion []uint16 } @@ -3461,4 +3469,4 @@ var parents = [5]parentRel{ 4: {lang: 0x529, script: 0x3c, maxScript: 0x3c, toRegion: 0x8d, fromRegion: []uint16{0xc6}}, } -// Total table size 26398 bytes (25KiB); checksum: 1C859EA7 +// Total table size 30244 bytes (29KiB); checksum: B6B15F30 diff --git a/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go b/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go index 575cea870..e5c53b1b3 100644 --- a/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go +++ b/vendor/golang.org/x/text/internal/utf8internal/utf8internal.go @@ -74,7 +74,7 @@ type AcceptRange struct { // AcceptRanges is a slice of AcceptRange values. For a given byte sequence b // -// AcceptRanges[First[b[0]]>>AcceptShift] +// AcceptRanges[First[b[0]]>>AcceptShift] // // will give the value of AcceptRange for the multi-byte UTF-8 sequence starting // at b[0]. diff --git a/vendor/golang.org/x/text/language/doc.go b/vendor/golang.org/x/text/language/doc.go index 8afecd50e..212b77c90 100644 --- a/vendor/golang.org/x/text/language/doc.go +++ b/vendor/golang.org/x/text/language/doc.go @@ -10,18 +10,17 @@ // and provides the user with the best experience // (see https://blog.golang.org/matchlang). // -// -// Matching preferred against supported languages +// # Matching preferred against supported languages // // A Matcher for an application that supports English, Australian English, // Danish, and standard Mandarin can be created as follows: // -// var matcher = language.NewMatcher([]language.Tag{ -// language.English, // The first language is used as fallback. -// language.MustParse("en-AU"), -// language.Danish, -// language.Chinese, -// }) +// var matcher = language.NewMatcher([]language.Tag{ +// language.English, // The first language is used as fallback. +// language.MustParse("en-AU"), +// language.Danish, +// language.Chinese, +// }) // // This list of supported languages is typically implied by the languages for // which there exists translations of the user interface. @@ -30,14 +29,14 @@ // language tags. // The MatchString finds best matches for such strings: // -// handler(w http.ResponseWriter, r *http.Request) { -// lang, _ := r.Cookie("lang") -// accept := r.Header.Get("Accept-Language") -// tag, _ := language.MatchStrings(matcher, lang.String(), accept) +// handler(w http.ResponseWriter, r *http.Request) { +// lang, _ := r.Cookie("lang") +// accept := r.Header.Get("Accept-Language") +// tag, _ := language.MatchStrings(matcher, lang.String(), accept) // -// // tag should now be used for the initialization of any -// // locale-specific service. -// } +// // tag should now be used for the initialization of any +// // locale-specific service. +// } // // The Matcher's Match method can be used to match Tags directly. // @@ -48,8 +47,7 @@ // For instance, it will know that a reader of Bokmål Danish can read Norwegian // and will know that Cantonese ("yue") is a good match for "zh-HK". // -// -// Using match results +// # Using match results // // To guarantee a consistent user experience to the user it is important to // use the same language tag for the selection of any locale-specific services. @@ -58,9 +56,9 @@ // More subtly confusing is using the wrong sorting order or casing // algorithm for a certain language. // -// All the packages in x/text that provide locale-specific services -// (e.g. collate, cases) should be initialized with the tag that was -// obtained at the start of an interaction with the user. +// All the packages in x/text that provide locale-specific services +// (e.g. collate, cases) should be initialized with the tag that was +// obtained at the start of an interaction with the user. // // Note that Tag that is returned by Match and MatchString may differ from any // of the supported languages, as it may contain carried over settings from @@ -70,8 +68,7 @@ // Match and MatchString both return the index of the matched supported tag // to simplify associating such data with the matched tag. // -// -// Canonicalization +// # Canonicalization // // If one uses the Matcher to compare languages one does not need to // worry about canonicalization. @@ -92,10 +89,9 @@ // equivalence relations. The CanonType type can be used to alter the // canonicalization form. // -// References +// # References // // BCP 47 - Tags for Identifying Languages http://tools.ietf.org/html/bcp47 -// package language // import "golang.org/x/text/language" // TODO: explanation on how to match languages for your own locale-specific diff --git a/vendor/golang.org/x/text/language/go1_1.go b/vendor/golang.org/x/text/language/go1_1.go deleted file mode 100644 index c7435583b..000000000 --- a/vendor/golang.org/x/text/language/go1_1.go +++ /dev/null @@ -1,39 +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. - -//go:build !go1.2 -// +build !go1.2 - -package language - -import "sort" - -func sortStable(s sort.Interface) { - ss := stableSort{ - s: s, - pos: make([]int, s.Len()), - } - for i := range ss.pos { - ss.pos[i] = i - } - sort.Sort(&ss) -} - -type stableSort struct { - s sort.Interface - pos []int -} - -func (s *stableSort) Len() int { - return len(s.pos) -} - -func (s *stableSort) Less(i, j int) bool { - return s.s.Less(i, j) || !s.s.Less(j, i) && s.pos[i] < s.pos[j] -} - -func (s *stableSort) Swap(i, j int) { - s.s.Swap(i, j) - s.pos[i], s.pos[j] = s.pos[j], s.pos[i] -} diff --git a/vendor/golang.org/x/text/language/go1_2.go b/vendor/golang.org/x/text/language/go1_2.go deleted file mode 100644 index 77aaaa299..000000000 --- a/vendor/golang.org/x/text/language/go1_2.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. - -//go:build go1.2 -// +build go1.2 - -package language - -import "sort" - -var sortStable = sort.Stable diff --git a/vendor/golang.org/x/text/language/match.go b/vendor/golang.org/x/text/language/match.go index f73492134..ee45f4947 100644 --- a/vendor/golang.org/x/text/language/match.go +++ b/vendor/golang.org/x/text/language/match.go @@ -545,7 +545,7 @@ type bestMatch struct { // match as the preferred match. // // If pin is true and have and tag are a strong match, it will henceforth only -// consider matches for this language. This corresponds to the nothing that most +// consider matches for this language. This corresponds to the idea that most // users have a strong preference for the first defined language. A user can // still prefer a second language over a dialect of the preferred language by // explicitly specifying dialects, e.g. "en, nl, en-GB". In this case pin should diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go index 59b041008..4d57222e7 100644 --- a/vendor/golang.org/x/text/language/parse.go +++ b/vendor/golang.org/x/text/language/parse.go @@ -6,6 +6,7 @@ package language import ( "errors" + "sort" "strconv" "strings" @@ -147,6 +148,7 @@ func update(b *language.Builder, part ...interface{}) (err error) { } var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight") +var errTagListTooLarge = errors.New("tag list exceeds max length") // ParseAcceptLanguage parses the contents of an Accept-Language header as // defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and @@ -164,6 +166,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { } }() + if strings.Count(s, "-") > 1000 { + return nil, nil, errTagListTooLarge + } + var entry string for s != "" { if entry, s = split(s, ','); entry == "" { @@ -201,7 +207,7 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) { tag = append(tag, t) q = append(q, float32(w)) } - sortStable(&tagSort{tag, q}) + sort.Stable(&tagSort{tag, q}) return tag, q, nil } diff --git a/vendor/golang.org/x/text/language/tables.go b/vendor/golang.org/x/text/language/tables.go index 96b57f610..34a732b69 100644 --- a/vendor/golang.org/x/text/language/tables.go +++ b/vendor/golang.org/x/text/language/tables.go @@ -39,12 +39,12 @@ const ( _Hani = 57 _Hans = 59 _Hant = 60 - _Qaaa = 143 - _Qaai = 151 - _Qabx = 192 - _Zinh = 245 - _Zyyy = 250 - _Zzzz = 251 + _Qaaa = 147 + _Qaai = 155 + _Qabx = 196 + _Zinh = 252 + _Zyyy = 257 + _Zzzz = 258 ) var regionToGroups = []uint8{ // 358 elements @@ -265,9 +265,9 @@ var matchScript = []scriptIntelligibility{ // 26 elements 13: {wantLang: 0x39d, haveLang: 0x139, wantScript: 0x36, haveScript: 0x5a, distance: 0xa}, 14: {wantLang: 0x3be, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa}, 15: {wantLang: 0x3fa, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa}, - 16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xcf, haveScript: 0x5a, distance: 0xa}, - 17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xde, haveScript: 0x5a, distance: 0xa}, - 18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe1, haveScript: 0x5a, distance: 0xa}, + 16: {wantLang: 0x40c, haveLang: 0x139, wantScript: 0xd4, haveScript: 0x5a, distance: 0xa}, + 17: {wantLang: 0x450, haveLang: 0x139, wantScript: 0xe3, haveScript: 0x5a, distance: 0xa}, + 18: {wantLang: 0x461, haveLang: 0x139, wantScript: 0xe6, haveScript: 0x5a, distance: 0xa}, 19: {wantLang: 0x46f, haveLang: 0x139, wantScript: 0x2c, haveScript: 0x5a, distance: 0xa}, 20: {wantLang: 0x476, haveLang: 0x3e2, wantScript: 0x5a, haveScript: 0x20, distance: 0xa}, 21: {wantLang: 0x4b4, haveLang: 0x139, wantScript: 0x5, haveScript: 0x5a, distance: 0xa}, diff --git a/vendor/golang.org/x/text/runes/runes.go b/vendor/golang.org/x/text/runes/runes.go index 71933696f..930e87fed 100644 --- a/vendor/golang.org/x/text/runes/runes.go +++ b/vendor/golang.org/x/text/runes/runes.go @@ -33,7 +33,7 @@ func In(rt *unicode.RangeTable) Set { return setFunc(func(r rune) bool { return unicode.Is(rt, r) }) } -// In creates a Set with a Contains method that returns true for all runes not +// NotIn creates a Set with a Contains method that returns true for all runes not // in the given RangeTable. func NotIn(rt *unicode.RangeTable) Set { return setFunc(func(r rune) bool { return !unicode.Is(rt, r) }) diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go index e4c081101..9d2ae547b 100644 --- a/vendor/golang.org/x/text/unicode/bidi/core.go +++ b/vendor/golang.org/x/text/unicode/bidi/core.go @@ -193,14 +193,14 @@ func (p *paragraph) run() { // // At the end of this function: // -// - The member variable matchingPDI is set to point to the index of the -// matching PDI character for each isolate initiator character. If there is -// no matching PDI, it is set to the length of the input text. For other -// characters, it is set to -1. -// - The member variable matchingIsolateInitiator is set to point to the -// index of the matching isolate initiator character for each PDI character. -// If there is no matching isolate initiator, or the character is not a PDI, -// it is set to -1. +// - The member variable matchingPDI is set to point to the index of the +// matching PDI character for each isolate initiator character. If there is +// no matching PDI, it is set to the length of the input text. For other +// characters, it is set to -1. +// - The member variable matchingIsolateInitiator is set to point to the +// index of the matching isolate initiator character for each PDI character. +// If there is no matching isolate initiator, or the character is not a PDI, +// it is set to -1. func (p *paragraph) determineMatchingIsolates() { p.matchingPDI = make([]int, p.Len()) p.matchingIsolateInitiator = make([]int, p.Len()) @@ -435,7 +435,7 @@ func maxLevel(a, b level) level { } // Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, -// either L or R, for each isolating run sequence. +// either L or R, for each isolating run sequence. func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence { length := len(indexes) types := make([]Class, length) @@ -495,9 +495,9 @@ func (s *isolatingRunSequence) resolveWeakTypes() { if t == NSM { s.types[i] = precedingCharacterType } else { - if t.in(LRI, RLI, FSI, PDI) { - precedingCharacterType = ON - } + // if t.in(LRI, RLI, FSI, PDI) { + // precedingCharacterType = ON + // } precedingCharacterType = t } } @@ -905,7 +905,7 @@ func (p *paragraph) getLevels(linebreaks []int) []level { // Lines are concatenated from left to right. So for example, the fifth // character from the left on the third line is // -// getReordering(linebreaks)[linebreaks[1] + 4] +// getReordering(linebreaks)[linebreaks[1] + 4] // // (linebreaks[1] is the position after the last character of the second // line, which is also the index of the first character on the third line, diff --git a/vendor/golang.org/x/text/unicode/norm/forminfo.go b/vendor/golang.org/x/text/unicode/norm/forminfo.go index 526c7033a..d69ccb4f9 100644 --- a/vendor/golang.org/x/text/unicode/norm/forminfo.go +++ b/vendor/golang.org/x/text/unicode/norm/forminfo.go @@ -110,10 +110,11 @@ func (p Properties) BoundaryAfter() bool { } // We pack quick check data in 4 bits: -// 5: Combines forward (0 == false, 1 == true) -// 4..3: NFC_QC Yes(00), No (10), or Maybe (11) -// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition. -// 1..0: Number of trailing non-starters. +// +// 5: Combines forward (0 == false, 1 == true) +// 4..3: NFC_QC Yes(00), No (10), or Maybe (11) +// 2: NFD_QC Yes (0) or No (1). No also means there is a decomposition. +// 1..0: Number of trailing non-starters. // // When all 4 bits are zero, the character is inert, meaning it is never // influenced by normalization. diff --git a/vendor/golang.org/x/text/unicode/norm/normalize.go b/vendor/golang.org/x/text/unicode/norm/normalize.go index 95efcf26e..4747ad07a 100644 --- a/vendor/golang.org/x/text/unicode/norm/normalize.go +++ b/vendor/golang.org/x/text/unicode/norm/normalize.go @@ -18,16 +18,17 @@ import ( // A Form denotes a canonical representation of Unicode code points. // The Unicode-defined normalization and equivalence forms are: // -// NFC Unicode Normalization Form C -// NFD Unicode Normalization Form D -// NFKC Unicode Normalization Form KC -// NFKD Unicode Normalization Form KD +// NFC Unicode Normalization Form C +// NFD Unicode Normalization Form D +// NFKC Unicode Normalization Form KC +// NFKD Unicode Normalization Form KD // // For a Form f, this documentation uses the notation f(x) to mean // the bytes or string x converted to the given form. // A position n in x is called a boundary if conversion to the form can // proceed independently on both sides: -// f(x) == append(f(x[0:n]), f(x[n:])...) +// +// f(x) == append(f(x[0:n]), f(x[n:])...) // // References: https://unicode.org/reports/tr15/ and // https://unicode.org/notes/tn5/. diff --git a/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go b/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go index 96a130d30..9115ef257 100644 --- a/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go +++ b/vendor/golang.org/x/text/unicode/norm/tables13.0.0.go @@ -7315,7 +7315,7 @@ const recompMapPacked = "" + "\x00V\x03\x03\x00\x00\x1e|" + // 0x00560303: 0x00001E7C "\x00v\x03\x03\x00\x00\x1e}" + // 0x00760303: 0x00001E7D "\x00V\x03#\x00\x00\x1e~" + // 0x00560323: 0x00001E7E - "\x00v\x03#\x00\x00\x1e\u007f" + // 0x00760323: 0x00001E7F + "\x00v\x03#\x00\x00\x1e\x7f" + // 0x00760323: 0x00001E7F "\x00W\x03\x00\x00\x00\x1e\x80" + // 0x00570300: 0x00001E80 "\x00w\x03\x00\x00\x00\x1e\x81" + // 0x00770300: 0x00001E81 "\x00W\x03\x01\x00\x00\x1e\x82" + // 0x00570301: 0x00001E82 @@ -7342,7 +7342,7 @@ const recompMapPacked = "" + "\x00t\x03\b\x00\x00\x1e\x97" + // 0x00740308: 0x00001E97 "\x00w\x03\n\x00\x00\x1e\x98" + // 0x0077030A: 0x00001E98 "\x00y\x03\n\x00\x00\x1e\x99" + // 0x0079030A: 0x00001E99 - "\x01\u007f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B + "\x01\x7f\x03\a\x00\x00\x1e\x9b" + // 0x017F0307: 0x00001E9B "\x00A\x03#\x00\x00\x1e\xa0" + // 0x00410323: 0x00001EA0 "\x00a\x03#\x00\x00\x1e\xa1" + // 0x00610323: 0x00001EA1 "\x00A\x03\t\x00\x00\x1e\xa2" + // 0x00410309: 0x00001EA2 diff --git a/vendor/golang.org/x/tools/AUTHORS b/vendor/golang.org/x/tools/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/golang.org/x/tools/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/tools/CONTRIBUTORS b/vendor/golang.org/x/tools/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/golang.org/x/tools/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/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go index d50826dbf..2ed25a750 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -22,26 +22,42 @@ package gcexportdata // import "golang.org/x/tools/go/gcexportdata" import ( "bufio" "bytes" + "encoding/json" "fmt" "go/token" "go/types" "io" "io/ioutil" + "os/exec" "golang.org/x/tools/go/internal/gcimporter" ) // Find returns the name of an object (.o) or archive (.a) file // containing type information for the specified import path, -// using the workspace layout conventions of go/build. +// using the go command. // If no file was found, an empty filename is returned. // // A relative srcDir is interpreted relative to the current working directory. // // Find also returns the package's resolved (canonical) import path, // reflecting the effects of srcDir and vendoring on importPath. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. func Find(importPath, srcDir string) (filename, path string) { - return gcimporter.FindPkg(importPath, srcDir) + cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) + cmd.Dir = srcDir + out, err := cmd.CombinedOutput() + if err != nil { + return "", "" + } + var data struct { + ImportPath string + Export string + } + json.Unmarshal(out, &data) + return data.Export, data.ImportPath } // NewReader returns a reader for the export data section of an object @@ -100,13 +116,29 @@ func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, // The indexed export format starts with an 'i'; the older // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. - if len(data) > 0 && data[0] == 'i' { - _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) - return pkg, err - } + if len(data) > 0 { + switch data[0] { + case 'i': + _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) + return pkg, err - _, pkg, err := gcimporter.BImportData(fset, imports, data, path) - return pkg, err + case 'v', 'c', 'd': + _, pkg, err := gcimporter.BImportData(fset, imports, data, path) + return pkg, err + + case 'u': + _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) + } + } + return nil, fmt.Errorf("empty export data for %s", path) } // Write writes encoded type information for the specified package to out. diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go index fe6ed9321..37a7247e2 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/importer.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go @@ -22,6 +22,9 @@ import ( // version-skew problems described in the documentation of this package, // or to control the FileSet or access the imports map populated during // package loading. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { return importer{fset, imports} } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go index 493bfa03b..e96c39600 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go @@ -181,8 +181,9 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func defer rc.Close() var hdr string + var size int64 buf := bufio.NewReader(rc) - if hdr, _, err = FindExportData(buf); err != nil { + if hdr, size, err = FindExportData(buf); err != nil { return } @@ -210,10 +211,27 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func // The indexed export format starts with an 'i'; the older // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. - if len(data) > 0 && data[0] == 'i' { - _, pkg, err = IImportData(fset, packages, data[1:], id) - } else { - _, pkg, err = BImportData(fset, packages, data, id) + if len(data) > 0 { + switch data[0] { + case 'i': + _, pkg, err := IImportData(fset, packages, data[1:], id) + return pkg, err + + case 'v', 'c', 'd': + _, pkg, err := BImportData(fset, packages, data, id) + return pkg, err + + case 'u': + _, pkg, err := UImportData(fset, packages, data[1:size], id) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id) + } } default: diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go index 28b91b865..4caa0f55d 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -17,6 +17,7 @@ import ( "go/token" "go/types" "io" + "math/big" "sort" "strings" @@ -512,7 +513,9 @@ func (r *importReader) value() (typ types.Type, val constant.Value) { val = constant.MakeString(r.string()) case types.IsInteger: - val = r.mpint(b) + var x big.Int + r.mpint(&x, b) + val = constant.Make(&x) case types.IsFloat: val = r.mpfloat(b) @@ -561,8 +564,8 @@ func intSize(b *types.Basic) (signed bool, maxBytes uint) { return } -func (r *importReader) mpint(b *types.Basic) constant.Value { - signed, maxBytes := intSize(b) +func (r *importReader) mpint(x *big.Int, typ *types.Basic) { + signed, maxBytes := intSize(typ) maxSmall := 256 - maxBytes if signed { @@ -581,7 +584,8 @@ func (r *importReader) mpint(b *types.Basic) constant.Value { v = ^v } } - return constant.MakeInt64(v) + x.SetInt64(v) + return } v := -n @@ -591,47 +595,23 @@ func (r *importReader) mpint(b *types.Basic) constant.Value { if v < 1 || uint(v) > maxBytes { errorf("weird decoding: %v, %v => %v", n, signed, v) } - - buf := make([]byte, v) - io.ReadFull(&r.declReader, buf) - - // convert to little endian - // TODO(gri) go/constant should have a more direct conversion function - // (e.g., once it supports a big.Float based implementation) - for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 { - buf[i], buf[j] = buf[j], buf[i] - } - - x := constant.MakeFromBytes(buf) + b := make([]byte, v) + io.ReadFull(&r.declReader, b) + x.SetBytes(b) if signed && n&1 != 0 { - x = constant.UnaryOp(token.SUB, x, 0) + x.Neg(x) } - return x } -func (r *importReader) mpfloat(b *types.Basic) constant.Value { - x := r.mpint(b) - if constant.Sign(x) == 0 { - return x +func (r *importReader) mpfloat(typ *types.Basic) constant.Value { + var mant big.Int + r.mpint(&mant, typ) + var f big.Float + f.SetInt(&mant) + if f.Sign() != 0 { + f.SetMantExp(&f, int(r.int64())) } - - exp := r.int64() - switch { - case exp > 0: - x = constant.Shift(x, token.SHL, uint(exp)) - // Ensure that the imported Kind is Float, else this constant may run into - // bitsize limits on overlarge integers. Eventually we can instead adopt - // the approach of CL 288632, but that CL relies on go/constant APIs that - // were introduced in go1.13. - // - // TODO(rFindley): sync the logic here with tip Go once we no longer - // support go1.12. - x = constant.ToFloat(x) - case exp < 0: - d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) - x = constant.BinaryOp(x, token.QUO, d) - } - return x + return constant.Make(&f) } func (r *importReader) ident() string { diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go new file mode 100644 index 000000000..286bf4454 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go @@ -0,0 +1,10 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !(go1.18 && goexperiment.unified) +// +build !go1.18 !goexperiment.unified + +package gcimporter + +const unifiedIR = false diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go new file mode 100644 index 000000000..b5d69ffbe --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go @@ -0,0 +1,10 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.18 && goexperiment.unified +// +build go1.18,goexperiment.unified + +package gcimporter + +const unifiedIR = true diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go new file mode 100644 index 000000000..8eb20729c --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go @@ -0,0 +1,19 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.18 +// +build !go1.18 + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" +) + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data") + return +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go new file mode 100644 index 000000000..3c1a43754 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go @@ -0,0 +1,612 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Derived from go/internal/gcimporter/ureader.go + +//go:build go1.18 +// +build go1.18 + +package gcimporter + +import ( + "go/token" + "go/types" + "strings" + + "golang.org/x/tools/go/internal/pkgbits" +) + +// A pkgReader holds the shared state for reading a unified IR package +// description. +type pkgReader struct { + pkgbits.PkgDecoder + + fake fakeFileSet + + ctxt *types.Context + imports map[string]*types.Package // previously imported packages, indexed by path + + // lazily initialized arrays corresponding to the unified IR + // PosBase, Pkg, and Type sections, respectively. + posBases []string // position bases (i.e., file names) + pkgs []*types.Package + typs []types.Type + + // laterFns holds functions that need to be invoked at the end of + // import reading. + laterFns []func() +} + +// later adds a function to be invoked at the end of import reading. +func (pr *pkgReader) later(fn func()) { + pr.laterFns = append(pr.laterFns, fn) +} + +// See cmd/compile/internal/noder.derivedInfo. +type derivedInfo struct { + idx pkgbits.Index + needed bool +} + +// See cmd/compile/internal/noder.typeInfo. +type typeInfo struct { + idx pkgbits.Index + derived bool +} + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + s := string(data) + s = s[:strings.LastIndex(s, "\n$$\n")] + input := pkgbits.NewPkgDecoder(path, s) + pkg = readUnifiedPackage(fset, nil, imports, input) + return +} + +// readUnifiedPackage reads a package description from the given +// unified IR export data decoder. +func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { + pr := pkgReader{ + PkgDecoder: input, + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*fileInfo), + }, + + ctxt: ctxt, + imports: imports, + + posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), + pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), + typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), + } + defer pr.fake.setLines() + + r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) + pkg := r.pkg() + r.Bool() // has init + + for i, n := 0, r.Len(); i < n; i++ { + // As if r.obj(), but avoiding the Scope.Lookup call, + // to avoid eager loading of imports. + r.Sync(pkgbits.SyncObject) + assert(!r.Bool()) + r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + assert(r.Len() == 0) + } + + r.Sync(pkgbits.SyncEOF) + + for _, fn := range pr.laterFns { + fn() + } + + pkg.MarkComplete() + return pkg +} + +// A reader holds the state for reading a single unified IR element +// within a package. +type reader struct { + pkgbits.Decoder + + p *pkgReader + + dict *readerDict +} + +// A readerDict holds the state for type parameters that parameterize +// the current unified IR element. +type readerDict struct { + // bounds is a slice of typeInfos corresponding to the underlying + // bounds of the element's type parameters. + bounds []typeInfo + + // tparams is a slice of the constructed TypeParams for the element. + tparams []*types.TypeParam + + // devived is a slice of types derived from tparams, which may be + // instantiated while reading the current element. + derived []derivedInfo + derivedTypes []types.Type // lazily instantiated from derived +} + +func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { + return &reader{ + Decoder: pr.NewDecoder(k, idx, marker), + p: pr, + } +} + +// @@@ Positions + +func (r *reader) pos() token.Pos { + r.Sync(pkgbits.SyncPos) + if !r.Bool() { + return token.NoPos + } + + // TODO(mdempsky): Delta encoding. + posBase := r.posBase() + line := r.Uint() + col := r.Uint() + return r.p.fake.pos(posBase, int(line), int(col)) +} + +func (r *reader) posBase() string { + return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) +} + +func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { + if b := pr.posBases[idx]; b != "" { + return b + } + + r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) + + // Within types2, position bases have a lot more details (e.g., + // keeping track of where //line directives appeared exactly). + // + // For go/types, we just track the file name. + + filename := r.String() + + if r.Bool() { // file base + // Was: "b = token.NewTrimmedFileBase(filename, true)" + } else { // line base + pos := r.pos() + line := r.Uint() + col := r.Uint() + + // Was: "b = token.NewLineBase(pos, filename, true, line, col)" + _, _, _ = pos, line, col + } + + b := filename + pr.posBases[idx] = b + return b +} + +// @@@ Packages + +func (r *reader) pkg() *types.Package { + r.Sync(pkgbits.SyncPkg) + return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) +} + +func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { + // TODO(mdempsky): Consider using some non-nil pointer to indicate + // the universe scope, so we don't need to keep re-reading it. + if pkg := pr.pkgs[idx]; pkg != nil { + return pkg + } + + pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() + pr.pkgs[idx] = pkg + return pkg +} + +func (r *reader) doPkg() *types.Package { + path := r.String() + switch path { + case "": + path = r.p.PkgPath() + case "builtin": + return nil // universe + case "unsafe": + return types.Unsafe + } + + if pkg := r.p.imports[path]; pkg != nil { + return pkg + } + + name := r.String() + + pkg := types.NewPackage(path, name) + r.p.imports[path] = pkg + + imports := make([]*types.Package, r.Len()) + for i := range imports { + imports[i] = r.pkg() + } + pkg.SetImports(imports) + + return pkg +} + +// @@@ Types + +func (r *reader) typ() types.Type { + return r.p.typIdx(r.typInfo(), r.dict) +} + +func (r *reader) typInfo() typeInfo { + r.Sync(pkgbits.SyncType) + if r.Bool() { + return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} + } + return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} +} + +func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { + idx := info.idx + var where *types.Type + if info.derived { + where = &dict.derivedTypes[idx] + idx = dict.derived[idx].idx + } else { + where = &pr.typs[idx] + } + + if typ := *where; typ != nil { + return typ + } + + r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) + r.dict = dict + + typ := r.doTyp() + assert(typ != nil) + + // See comment in pkgReader.typIdx explaining how this happens. + if prev := *where; prev != nil { + return prev + } + + *where = typ + return typ +} + +func (r *reader) doTyp() (res types.Type) { + switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { + default: + errorf("unhandled type tag: %v", tag) + panic("unreachable") + + case pkgbits.TypeBasic: + return types.Typ[r.Len()] + + case pkgbits.TypeNamed: + obj, targs := r.obj() + name := obj.(*types.TypeName) + if len(targs) != 0 { + t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) + return t + } + return name.Type() + + case pkgbits.TypeTypeParam: + return r.dict.tparams[r.Len()] + + case pkgbits.TypeArray: + len := int64(r.Uint64()) + return types.NewArray(r.typ(), len) + case pkgbits.TypeChan: + dir := types.ChanDir(r.Len()) + return types.NewChan(dir, r.typ()) + case pkgbits.TypeMap: + return types.NewMap(r.typ(), r.typ()) + case pkgbits.TypePointer: + return types.NewPointer(r.typ()) + case pkgbits.TypeSignature: + return r.signature(nil, nil, nil) + case pkgbits.TypeSlice: + return types.NewSlice(r.typ()) + case pkgbits.TypeStruct: + return r.structType() + case pkgbits.TypeInterface: + return r.interfaceType() + case pkgbits.TypeUnion: + return r.unionType() + } +} + +func (r *reader) structType() *types.Struct { + fields := make([]*types.Var, r.Len()) + var tags []string + for i := range fields { + pos := r.pos() + pkg, name := r.selector() + ftyp := r.typ() + tag := r.String() + embedded := r.Bool() + + fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) + if tag != "" { + for len(tags) < i { + tags = append(tags, "") + } + tags = append(tags, tag) + } + } + return types.NewStruct(fields, tags) +} + +func (r *reader) unionType() *types.Union { + terms := make([]*types.Term, r.Len()) + for i := range terms { + terms[i] = types.NewTerm(r.Bool(), r.typ()) + } + return types.NewUnion(terms) +} + +func (r *reader) interfaceType() *types.Interface { + methods := make([]*types.Func, r.Len()) + embeddeds := make([]types.Type, r.Len()) + implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() + + for i := range methods { + pos := r.pos() + pkg, name := r.selector() + mtyp := r.signature(nil, nil, nil) + methods[i] = types.NewFunc(pos, pkg, name, mtyp) + } + + for i := range embeddeds { + embeddeds[i] = r.typ() + } + + iface := types.NewInterfaceType(methods, embeddeds) + if implicit { + iface.MarkImplicit() + } + return iface +} + +func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { + r.Sync(pkgbits.SyncSignature) + + params := r.params() + results := r.params() + variadic := r.Bool() + + return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) +} + +func (r *reader) params() *types.Tuple { + r.Sync(pkgbits.SyncParams) + + params := make([]*types.Var, r.Len()) + for i := range params { + params[i] = r.param() + } + + return types.NewTuple(params...) +} + +func (r *reader) param() *types.Var { + r.Sync(pkgbits.SyncParam) + + pos := r.pos() + pkg, name := r.localIdent() + typ := r.typ() + + return types.NewParam(pos, pkg, name, typ) +} + +// @@@ Objects + +func (r *reader) obj() (types.Object, []types.Type) { + r.Sync(pkgbits.SyncObject) + + assert(!r.Bool()) + + pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + obj := pkgScope(pkg).Lookup(name) + + targs := make([]types.Type, r.Len()) + for i := range targs { + targs[i] = r.typ() + } + + return obj, targs +} + +func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { + rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) + + objPkg, objName := rname.qualifiedIdent() + assert(objName != "") + + tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) + + if tag == pkgbits.ObjStub { + assert(objPkg == nil || objPkg == types.Unsafe) + return objPkg, objName + } + + if objPkg.Scope().Lookup(objName) == nil { + dict := pr.objDictIdx(idx) + + r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) + r.dict = dict + + declare := func(obj types.Object) { + objPkg.Scope().Insert(obj) + } + + switch tag { + default: + panic("weird") + + case pkgbits.ObjAlias: + pos := r.pos() + typ := r.typ() + declare(types.NewTypeName(pos, objPkg, objName, typ)) + + case pkgbits.ObjConst: + pos := r.pos() + typ := r.typ() + val := r.Value() + declare(types.NewConst(pos, objPkg, objName, typ, val)) + + case pkgbits.ObjFunc: + pos := r.pos() + tparams := r.typeParamNames() + sig := r.signature(nil, nil, tparams) + declare(types.NewFunc(pos, objPkg, objName, sig)) + + case pkgbits.ObjType: + pos := r.pos() + + obj := types.NewTypeName(pos, objPkg, objName, nil) + named := types.NewNamed(obj, nil, nil) + declare(obj) + + named.SetTypeParams(r.typeParamNames()) + + // TODO(mdempsky): Rewrite receiver types to underlying is an + // Interface? The go/types importer does this (I think because + // unit tests expected that), but cmd/compile doesn't care + // about it, so maybe we can avoid worrying about that here. + rhs := r.typ() + r.p.later(func() { + underlying := rhs.Underlying() + named.SetUnderlying(underlying) + }) + + for i, n := 0, r.Len(); i < n; i++ { + named.AddMethod(r.method()) + } + + case pkgbits.ObjVar: + pos := r.pos() + typ := r.typ() + declare(types.NewVar(pos, objPkg, objName, typ)) + } + } + + return objPkg, objName +} + +func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { + r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) + + var dict readerDict + + if implicits := r.Len(); implicits != 0 { + errorf("unexpected object with %v implicit type parameter(s)", implicits) + } + + dict.bounds = make([]typeInfo, r.Len()) + for i := range dict.bounds { + dict.bounds[i] = r.typInfo() + } + + dict.derived = make([]derivedInfo, r.Len()) + dict.derivedTypes = make([]types.Type, len(dict.derived)) + for i := range dict.derived { + dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()} + } + + // function references follow, but reader doesn't need those + + return &dict +} + +func (r *reader) typeParamNames() []*types.TypeParam { + r.Sync(pkgbits.SyncTypeParamNames) + + // Note: This code assumes it only processes objects without + // implement type parameters. This is currently fine, because + // reader is only used to read in exported declarations, which are + // always package scoped. + + if len(r.dict.bounds) == 0 { + return nil + } + + // Careful: Type parameter lists may have cycles. To allow for this, + // we construct the type parameter list in two passes: first we + // create all the TypeNames and TypeParams, then we construct and + // set the bound type. + + r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds)) + for i := range r.dict.bounds { + pos := r.pos() + pkg, name := r.localIdent() + + tname := types.NewTypeName(pos, pkg, name, nil) + r.dict.tparams[i] = types.NewTypeParam(tname, nil) + } + + typs := make([]types.Type, len(r.dict.bounds)) + for i, bound := range r.dict.bounds { + typs[i] = r.p.typIdx(bound, r.dict) + } + + // TODO(mdempsky): This is subtle, elaborate further. + // + // We have to save tparams outside of the closure, because + // typeParamNames() can be called multiple times with the same + // dictionary instance. + // + // Also, this needs to happen later to make sure SetUnderlying has + // been called. + // + // TODO(mdempsky): Is it safe to have a single "later" slice or do + // we need to have multiple passes? See comments on CL 386002 and + // go.dev/issue/52104. + tparams := r.dict.tparams + r.p.later(func() { + for i, typ := range typs { + tparams[i].SetConstraint(typ) + } + }) + + return r.dict.tparams +} + +func (r *reader) method() *types.Func { + r.Sync(pkgbits.SyncMethod) + pos := r.pos() + pkg, name := r.selector() + + rparams := r.typeParamNames() + sig := r.signature(r.param(), rparams, nil) + + _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. + return types.NewFunc(pos, pkg, name, sig) +} + +func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } +func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } +func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } + +func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { + r.Sync(marker) + return r.pkg(), r.String() +} + +// pkgScope returns pkg.Scope(). +// If pkg is nil, it returns types.Universe instead. +// +// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. +func pkgScope(pkg *types.Package) *types.Scope { + if pkg != nil { + return pkg.Scope() + } + return types.Universe +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go new file mode 100644 index 000000000..f0cabde96 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go @@ -0,0 +1,77 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +// A Code is an enum value that can be encoded into bitstreams. +// +// Code types are preferable for enum types, because they allow +// Decoder to detect desyncs. +type Code interface { + // Marker returns the SyncMarker for the Code's dynamic type. + Marker() SyncMarker + + // Value returns the Code's ordinal value. + Value() int +} + +// A CodeVal distinguishes among go/constant.Value encodings. +type CodeVal int + +func (c CodeVal) Marker() SyncMarker { return SyncVal } +func (c CodeVal) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ValBool CodeVal = iota + ValString + ValInt64 + ValBigInt + ValBigRat + ValBigFloat +) + +// A CodeType distinguishes among go/types.Type encodings. +type CodeType int + +func (c CodeType) Marker() SyncMarker { return SyncType } +func (c CodeType) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + TypeBasic CodeType = iota + TypeNamed + TypePointer + TypeSlice + TypeArray + TypeChan + TypeMap + TypeSignature + TypeStruct + TypeInterface + TypeUnion + TypeTypeParam +) + +// A CodeObj distinguishes among go/types.Object encodings. +type CodeObj int + +func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } +func (c CodeObj) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ObjAlias CodeObj = iota + ObjConst + ObjType + ObjFunc + ObjVar + ObjStub +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go new file mode 100644 index 000000000..2bc793668 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go @@ -0,0 +1,433 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import ( + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "math/big" + "os" + "runtime" + "strings" +) + +// A PkgDecoder provides methods for decoding a package's Unified IR +// export data. +type PkgDecoder struct { + // version is the file format version. + version uint32 + + // sync indicates whether the file uses sync markers. + sync bool + + // pkgPath is the package path for the package to be decoded. + // + // TODO(mdempsky): Remove; unneeded since CL 391014. + pkgPath string + + // elemData is the full data payload of the encoded package. + // Elements are densely and contiguously packed together. + // + // The last 8 bytes of elemData are the package fingerprint. + elemData string + + // elemEnds stores the byte-offset end positions of element + // bitstreams within elemData. + // + // For example, element I's bitstream data starts at elemEnds[I-1] + // (or 0, if I==0) and ends at elemEnds[I]. + // + // Note: elemEnds is indexed by absolute indices, not + // section-relative indices. + elemEnds []uint32 + + // elemEndsEnds stores the index-offset end positions of relocation + // sections within elemEnds. + // + // For example, section K's end positions start at elemEndsEnds[K-1] + // (or 0, if K==0) and end at elemEndsEnds[K]. + elemEndsEnds [numRelocs]uint32 +} + +// PkgPath returns the package path for the package +// +// TODO(mdempsky): Remove; unneeded since CL 391014. +func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath } + +// SyncMarkers reports whether pr uses sync markers. +func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } + +// NewPkgDecoder returns a PkgDecoder initialized to read the Unified +// IR export data from input. pkgPath is the package path for the +// compilation unit that produced the export data. +// +// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014. +func NewPkgDecoder(pkgPath, input string) PkgDecoder { + pr := PkgDecoder{ + pkgPath: pkgPath, + } + + // TODO(mdempsky): Implement direct indexing of input string to + // avoid copying the position information. + + r := strings.NewReader(input) + + assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil) + + switch pr.version { + default: + panic(fmt.Errorf("unsupported version: %v", pr.version)) + case 0: + // no flags + case 1: + var flags uint32 + assert(binary.Read(r, binary.LittleEndian, &flags) == nil) + pr.sync = flags&flagSyncMarkers != 0 + } + + assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil) + + pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) + assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) + + pos, err := r.Seek(0, os.SEEK_CUR) + assert(err == nil) + + pr.elemData = input[pos:] + assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1])) + + return pr +} + +// NumElems returns the number of elements in section k. +func (pr *PkgDecoder) NumElems(k RelocKind) int { + count := int(pr.elemEndsEnds[k]) + if k > 0 { + count -= int(pr.elemEndsEnds[k-1]) + } + return count +} + +// TotalElems returns the total number of elements across all sections. +func (pr *PkgDecoder) TotalElems() int { + return len(pr.elemEnds) +} + +// Fingerprint returns the package fingerprint. +func (pr *PkgDecoder) Fingerprint() [8]byte { + var fp [8]byte + copy(fp[:], pr.elemData[len(pr.elemData)-8:]) + return fp +} + +// AbsIdx returns the absolute index for the given (section, index) +// pair. +func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { + absIdx := int(idx) + if k > 0 { + absIdx += int(pr.elemEndsEnds[k-1]) + } + if absIdx >= int(pr.elemEndsEnds[k]) { + errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) + } + return absIdx +} + +// DataIdx returns the raw element bitstream for the given (section, +// index) pair. +func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string { + absIdx := pr.AbsIdx(k, idx) + + var start uint32 + if absIdx > 0 { + start = pr.elemEnds[absIdx-1] + } + end := pr.elemEnds[absIdx] + + return pr.elemData[start:end] +} + +// StringIdx returns the string value for the given string index. +func (pr *PkgDecoder) StringIdx(idx Index) string { + return pr.DataIdx(RelocString, idx) +} + +// NewDecoder returns a Decoder for the given (section, index) pair, +// and decodes the given SyncMarker from the element bitstream. +func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { + r := pr.NewDecoderRaw(k, idx) + r.Sync(marker) + return r +} + +// NewDecoderRaw returns a Decoder for the given (section, index) pair. +// +// Most callers should use NewDecoder instead. +func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { + r := Decoder{ + common: pr, + k: k, + Idx: idx, + } + + // TODO(mdempsky) r.data.Reset(...) after #44505 is resolved. + r.Data = *strings.NewReader(pr.DataIdx(k, idx)) + + r.Sync(SyncRelocs) + r.Relocs = make([]RelocEnt, r.Len()) + for i := range r.Relocs { + r.Sync(SyncReloc) + r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} + } + + return r +} + +// A Decoder provides methods for decoding an individual element's +// bitstream data. +type Decoder struct { + common *PkgDecoder + + Relocs []RelocEnt + Data strings.Reader + + k RelocKind + Idx Index +} + +func (r *Decoder) checkErr(err error) { + if err != nil { + errorf("unexpected decoding error: %w", err) + } +} + +func (r *Decoder) rawUvarint() uint64 { + x, err := binary.ReadUvarint(&r.Data) + r.checkErr(err) + return x +} + +func (r *Decoder) rawVarint() int64 { + ux := r.rawUvarint() + + // Zig-zag decode. + x := int64(ux >> 1) + if ux&1 != 0 { + x = ^x + } + return x +} + +func (r *Decoder) rawReloc(k RelocKind, idx int) Index { + e := r.Relocs[idx] + assert(e.Kind == k) + return e.Idx +} + +// Sync decodes a sync marker from the element bitstream and asserts +// that it matches the expected marker. +// +// If r.common.sync is false, then Sync is a no-op. +func (r *Decoder) Sync(mWant SyncMarker) { + if !r.common.sync { + return + } + + pos, _ := r.Data.Seek(0, os.SEEK_CUR) // TODO(mdempsky): io.SeekCurrent after #44505 is resolved + mHave := SyncMarker(r.rawUvarint()) + writerPCs := make([]int, r.rawUvarint()) + for i := range writerPCs { + writerPCs[i] = int(r.rawUvarint()) + } + + if mHave == mWant { + return + } + + // There's some tension here between printing: + // + // (1) full file paths that tools can recognize (e.g., so emacs + // hyperlinks the "file:line" text for easy navigation), or + // + // (2) short file paths that are easier for humans to read (e.g., by + // omitting redundant or irrelevant details, so it's easier to + // focus on the useful bits that remain). + // + // The current formatting favors the former, as it seems more + // helpful in practice. But perhaps the formatting could be improved + // to better address both concerns. For example, use relative file + // paths if they would be shorter, or rewrite file paths to contain + // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how + // to reliably expand that again. + + fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos) + + fmt.Printf("\nfound %v, written at:\n", mHave) + if len(writerPCs) == 0 { + fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath) + } + for _, pc := range writerPCs { + fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc))) + } + + fmt.Printf("\nexpected %v, reading at:\n", mWant) + var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size? + n := runtime.Callers(2, readerPCs[:]) + for _, pc := range fmtFrames(readerPCs[:n]...) { + fmt.Printf("\t%s\n", pc) + } + + // We already printed a stack trace for the reader, so now we can + // simply exit. Printing a second one with panic or base.Fatalf + // would just be noise. + os.Exit(1) +} + +// Bool decodes and returns a bool value from the element bitstream. +func (r *Decoder) Bool() bool { + r.Sync(SyncBool) + x, err := r.Data.ReadByte() + r.checkErr(err) + assert(x < 2) + return x != 0 +} + +// Int64 decodes and returns an int64 value from the element bitstream. +func (r *Decoder) Int64() int64 { + r.Sync(SyncInt64) + return r.rawVarint() +} + +// Int64 decodes and returns a uint64 value from the element bitstream. +func (r *Decoder) Uint64() uint64 { + r.Sync(SyncUint64) + return r.rawUvarint() +} + +// Len decodes and returns a non-negative int value from the element bitstream. +func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v } + +// Int decodes and returns an int value from the element bitstream. +func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v } + +// Uint decodes and returns a uint value from the element bitstream. +func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v } + +// Code decodes a Code value from the element bitstream and returns +// its ordinal value. It's the caller's responsibility to convert the +// result to an appropriate Code type. +// +// TODO(mdempsky): Ideally this method would have signature "Code[T +// Code] T" instead, but we don't allow generic methods and the +// compiler can't depend on generics yet anyway. +func (r *Decoder) Code(mark SyncMarker) int { + r.Sync(mark) + return r.Len() +} + +// Reloc decodes a relocation of expected section k from the element +// bitstream and returns an index to the referenced element. +func (r *Decoder) Reloc(k RelocKind) Index { + r.Sync(SyncUseReloc) + return r.rawReloc(k, r.Len()) +} + +// String decodes and returns a string value from the element +// bitstream. +func (r *Decoder) String() string { + r.Sync(SyncString) + return r.common.StringIdx(r.Reloc(RelocString)) +} + +// Strings decodes and returns a variable-length slice of strings from +// the element bitstream. +func (r *Decoder) Strings() []string { + res := make([]string, r.Len()) + for i := range res { + res[i] = r.String() + } + return res +} + +// Value decodes and returns a constant.Value from the element +// bitstream. +func (r *Decoder) Value() constant.Value { + r.Sync(SyncValue) + isComplex := r.Bool() + val := r.scalar() + if isComplex { + val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar())) + } + return val +} + +func (r *Decoder) scalar() constant.Value { + switch tag := CodeVal(r.Code(SyncVal)); tag { + default: + panic(fmt.Errorf("unexpected scalar tag: %v", tag)) + + case ValBool: + return constant.MakeBool(r.Bool()) + case ValString: + return constant.MakeString(r.String()) + case ValInt64: + return constant.MakeInt64(r.Int64()) + case ValBigInt: + return constant.Make(r.bigInt()) + case ValBigRat: + num := r.bigInt() + denom := r.bigInt() + return constant.Make(new(big.Rat).SetFrac(num, denom)) + case ValBigFloat: + return constant.Make(r.bigFloat()) + } +} + +func (r *Decoder) bigInt() *big.Int { + v := new(big.Int).SetBytes([]byte(r.String())) + if r.Bool() { + v.Neg(v) + } + return v +} + +func (r *Decoder) bigFloat() *big.Float { + v := new(big.Float).SetPrec(512) + assert(v.UnmarshalText([]byte(r.String())) == nil) + return v +} + +// @@@ Helpers + +// TODO(mdempsky): These should probably be removed. I think they're a +// smell that the export data format is not yet quite right. + +// PeekPkgPath returns the package path for the specified package +// index. +func (pr *PkgDecoder) PeekPkgPath(idx Index) string { + r := pr.NewDecoder(RelocPkg, idx, SyncPkgDef) + path := r.String() + if path == "" { + path = pr.pkgPath + } + return path +} + +// PeekObj returns the package path, object name, and CodeObj for the +// specified object index. +func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { + r := pr.NewDecoder(RelocName, idx, SyncObject1) + r.Sync(SyncSym) + r.Sync(SyncPkg) + path := pr.PeekPkgPath(r.Reloc(RelocPkg)) + name := r.String() + assert(name != "") + + tag := CodeObj(r.Code(SyncCodeObj)) + + return path, name, tag +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go new file mode 100644 index 000000000..c8a2796b5 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go @@ -0,0 +1,32 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package pkgbits implements low-level coding abstractions for +// Unified IR's export data format. +// +// At a low-level, a package is a collection of bitstream elements. +// Each element has a "kind" and a dense, non-negative index. +// Elements can be randomly accessed given their kind and index. +// +// Individual elements are sequences of variable-length values (e.g., +// integers, booleans, strings, go/constant values, cross-references +// to other elements). Package pkgbits provides APIs for encoding and +// decoding these low-level values, but the details of mapping +// higher-level Go constructs into elements is left to higher-level +// abstractions. +// +// Elements may cross-reference each other with "relocations." For +// example, an element representing a pointer type has a relocation +// referring to the element type. +// +// Go constructs may be composed as a constellation of multiple +// elements. For example, a declared function may have one element to +// describe the object (e.g., its name, type, position), and a +// separate element to describe its function body. This allows readers +// some flexibility in efficiently seeking or re-reading data (e.g., +// inlining requires re-reading the function body for each inlined +// call, without needing to re-read the object-level details). +// +// This is a copy of internal/pkgbits in the Go implementation. +package pkgbits diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go new file mode 100644 index 000000000..c50c838ca --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go @@ -0,0 +1,379 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import ( + "bytes" + "crypto/md5" + "encoding/binary" + "go/constant" + "io" + "math/big" + "runtime" +) + +// currentVersion is the current version number. +// +// - v0: initial prototype +// +// - v1: adds the flags uint32 word +const currentVersion uint32 = 1 + +// A PkgEncoder provides methods for encoding a package's Unified IR +// export data. +type PkgEncoder struct { + // elems holds the bitstream for previously encoded elements. + elems [numRelocs][]string + + // stringsIdx maps previously encoded strings to their index within + // the RelocString section, to allow deduplication. That is, + // elems[RelocString][stringsIdx[s]] == s (if present). + stringsIdx map[string]Index + + // syncFrames is the number of frames to write at each sync + // marker. A negative value means sync markers are omitted. + syncFrames int +} + +// SyncMarkers reports whether pw uses sync markers. +func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } + +// NewPkgEncoder returns an initialized PkgEncoder. +// +// syncFrames is the number of caller frames that should be serialized +// at Sync points. Serializing additional frames results in larger +// export data files, but can help diagnosing desync errors in +// higher-level Unified IR reader/writer code. If syncFrames is +// negative, then sync markers are omitted entirely. +func NewPkgEncoder(syncFrames int) PkgEncoder { + return PkgEncoder{ + stringsIdx: make(map[string]Index), + syncFrames: syncFrames, + } +} + +// DumpTo writes the package's encoded data to out0 and returns the +// package fingerprint. +func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { + h := md5.New() + out := io.MultiWriter(out0, h) + + writeUint32 := func(x uint32) { + assert(binary.Write(out, binary.LittleEndian, x) == nil) + } + + writeUint32(currentVersion) + + var flags uint32 + if pw.SyncMarkers() { + flags |= flagSyncMarkers + } + writeUint32(flags) + + // Write elemEndsEnds. + var sum uint32 + for _, elems := range &pw.elems { + sum += uint32(len(elems)) + writeUint32(sum) + } + + // Write elemEnds. + sum = 0 + for _, elems := range &pw.elems { + for _, elem := range elems { + sum += uint32(len(elem)) + writeUint32(sum) + } + } + + // Write elemData. + for _, elems := range &pw.elems { + for _, elem := range elems { + _, err := io.WriteString(out, elem) + assert(err == nil) + } + } + + // Write fingerprint. + copy(fingerprint[:], h.Sum(nil)) + _, err := out0.Write(fingerprint[:]) + assert(err == nil) + + return +} + +// StringIdx adds a string value to the strings section, if not +// already present, and returns its index. +func (pw *PkgEncoder) StringIdx(s string) Index { + if idx, ok := pw.stringsIdx[s]; ok { + assert(pw.elems[RelocString][idx] == s) + return idx + } + + idx := Index(len(pw.elems[RelocString])) + pw.elems[RelocString] = append(pw.elems[RelocString], s) + pw.stringsIdx[s] = idx + return idx +} + +// NewEncoder returns an Encoder for a new element within the given +// section, and encodes the given SyncMarker as the start of the +// element bitstream. +func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder { + e := pw.NewEncoderRaw(k) + e.Sync(marker) + return e +} + +// NewEncoderRaw returns an Encoder for a new element within the given +// section. +// +// Most callers should use NewEncoder instead. +func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { + idx := Index(len(pw.elems[k])) + pw.elems[k] = append(pw.elems[k], "") // placeholder + + return Encoder{ + p: pw, + k: k, + Idx: idx, + } +} + +// An Encoder provides methods for encoding an individual element's +// bitstream data. +type Encoder struct { + p *PkgEncoder + + Relocs []RelocEnt + Data bytes.Buffer // accumulated element bitstream data + + encodingRelocHeader bool + + k RelocKind + Idx Index // index within relocation section +} + +// Flush finalizes the element's bitstream and returns its Index. +func (w *Encoder) Flush() Index { + var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved + + // Backup the data so we write the relocations at the front. + var tmp bytes.Buffer + io.Copy(&tmp, &w.Data) + + // TODO(mdempsky): Consider writing these out separately so they're + // easier to strip, along with function bodies, so that we can prune + // down to just the data that's relevant to go/types. + if w.encodingRelocHeader { + panic("encodingRelocHeader already true; recursive flush?") + } + w.encodingRelocHeader = true + w.Sync(SyncRelocs) + w.Len(len(w.Relocs)) + for _, rEnt := range w.Relocs { + w.Sync(SyncReloc) + w.Len(int(rEnt.Kind)) + w.Len(int(rEnt.Idx)) + } + + io.Copy(&sb, &w.Data) + io.Copy(&sb, &tmp) + w.p.elems[w.k][w.Idx] = sb.String() + + return w.Idx +} + +func (w *Encoder) checkErr(err error) { + if err != nil { + errorf("unexpected encoding error: %v", err) + } +} + +func (w *Encoder) rawUvarint(x uint64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + _, err := w.Data.Write(buf[:n]) + w.checkErr(err) +} + +func (w *Encoder) rawVarint(x int64) { + // Zig-zag encode. + ux := uint64(x) << 1 + if x < 0 { + ux = ^ux + } + + w.rawUvarint(ux) +} + +func (w *Encoder) rawReloc(r RelocKind, idx Index) int { + // TODO(mdempsky): Use map for lookup; this takes quadratic time. + for i, rEnt := range w.Relocs { + if rEnt.Kind == r && rEnt.Idx == idx { + return i + } + } + + i := len(w.Relocs) + w.Relocs = append(w.Relocs, RelocEnt{r, idx}) + return i +} + +func (w *Encoder) Sync(m SyncMarker) { + if !w.p.SyncMarkers() { + return + } + + // Writing out stack frame string references requires working + // relocations, but writing out the relocations themselves involves + // sync markers. To prevent infinite recursion, we simply trim the + // stack frame for sync markers within the relocation header. + var frames []string + if !w.encodingRelocHeader && w.p.syncFrames > 0 { + pcs := make([]uintptr, w.p.syncFrames) + n := runtime.Callers(2, pcs) + frames = fmtFrames(pcs[:n]...) + } + + // TODO(mdempsky): Save space by writing out stack frames as a + // linked list so we can share common stack frames. + w.rawUvarint(uint64(m)) + w.rawUvarint(uint64(len(frames))) + for _, frame := range frames { + w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame)))) + } +} + +// Bool encodes and writes a bool value into the element bitstream, +// and then returns the bool value. +// +// For simple, 2-alternative encodings, the idiomatic way to call Bool +// is something like: +// +// if w.Bool(x != 0) { +// // alternative #1 +// } else { +// // alternative #2 +// } +// +// For multi-alternative encodings, use Code instead. +func (w *Encoder) Bool(b bool) bool { + w.Sync(SyncBool) + var x byte + if b { + x = 1 + } + err := w.Data.WriteByte(x) + w.checkErr(err) + return b +} + +// Int64 encodes and writes an int64 value into the element bitstream. +func (w *Encoder) Int64(x int64) { + w.Sync(SyncInt64) + w.rawVarint(x) +} + +// Uint64 encodes and writes a uint64 value into the element bitstream. +func (w *Encoder) Uint64(x uint64) { + w.Sync(SyncUint64) + w.rawUvarint(x) +} + +// Len encodes and writes a non-negative int value into the element bitstream. +func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) } + +// Int encodes and writes an int value into the element bitstream. +func (w *Encoder) Int(x int) { w.Int64(int64(x)) } + +// Len encodes and writes a uint value into the element bitstream. +func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } + +// Reloc encodes and writes a relocation for the given (section, +// index) pair into the element bitstream. +// +// Note: Only the index is formally written into the element +// bitstream, so bitstream decoders must know from context which +// section an encoded relocation refers to. +func (w *Encoder) Reloc(r RelocKind, idx Index) { + w.Sync(SyncUseReloc) + w.Len(w.rawReloc(r, idx)) +} + +// Code encodes and writes a Code value into the element bitstream. +func (w *Encoder) Code(c Code) { + w.Sync(c.Marker()) + w.Len(c.Value()) +} + +// String encodes and writes a string value into the element +// bitstream. +// +// Internally, strings are deduplicated by adding them to the strings +// section (if not already present), and then writing a relocation +// into the element bitstream. +func (w *Encoder) String(s string) { + w.Sync(SyncString) + w.Reloc(RelocString, w.p.StringIdx(s)) +} + +// Strings encodes and writes a variable-length slice of strings into +// the element bitstream. +func (w *Encoder) Strings(ss []string) { + w.Len(len(ss)) + for _, s := range ss { + w.String(s) + } +} + +// Value encodes and writes a constant.Value into the element +// bitstream. +func (w *Encoder) Value(val constant.Value) { + w.Sync(SyncValue) + if w.Bool(val.Kind() == constant.Complex) { + w.scalar(constant.Real(val)) + w.scalar(constant.Imag(val)) + } else { + w.scalar(val) + } +} + +func (w *Encoder) scalar(val constant.Value) { + switch v := constant.Val(val).(type) { + default: + errorf("unhandled %v (%v)", val, val.Kind()) + case bool: + w.Code(ValBool) + w.Bool(v) + case string: + w.Code(ValString) + w.String(v) + case int64: + w.Code(ValInt64) + w.Int64(v) + case *big.Int: + w.Code(ValBigInt) + w.bigInt(v) + case *big.Rat: + w.Code(ValBigRat) + w.bigInt(v.Num()) + w.bigInt(v.Denom()) + case *big.Float: + w.Code(ValBigFloat) + w.bigFloat(v) + } +} + +func (w *Encoder) bigInt(v *big.Int) { + b := v.Bytes() + w.String(string(b)) // TODO: More efficient encoding. + w.Bool(v.Sign() < 0) +} + +func (w *Encoder) bigFloat(v *big.Float) { + b := v.Append(nil, 'p', -1) + w.String(string(b)) // TODO: More efficient encoding. +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go new file mode 100644 index 000000000..654222745 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go @@ -0,0 +1,9 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +const ( + flagSyncMarkers = 1 << iota // file format contains sync markers +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go new file mode 100644 index 000000000..5294f6a63 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go @@ -0,0 +1,21 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build !go1.7 +// +build !go1.7 + +// TODO(mdempsky): Remove after #44505 is resolved + +package pkgbits + +import "runtime" + +func walkFrames(pcs []uintptr, visit frameVisitor) { + for _, pc := range pcs { + fn := runtime.FuncForPC(pc) + file, line := fn.FileLine(pc) + + visit(file, line, fn.Name(), pc-fn.Entry()) + } +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go new file mode 100644 index 000000000..2324ae7ad --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go @@ -0,0 +1,28 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build go1.7 +// +build go1.7 + +package pkgbits + +import "runtime" + +// walkFrames calls visit for each call frame represented by pcs. +// +// pcs should be a slice of PCs, as returned by runtime.Callers. +func walkFrames(pcs []uintptr, visit frameVisitor) { + if len(pcs) == 0 { + return + } + + frames := runtime.CallersFrames(pcs) + for { + frame, more := frames.Next() + visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) + if !more { + return + } + } +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go new file mode 100644 index 000000000..7a8f04ab3 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go @@ -0,0 +1,42 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +// A RelocKind indicates a particular section within a unified IR export. +type RelocKind int + +// An Index represents a bitstream element index within a particular +// section. +type Index int + +// A relocEnt (relocation entry) is an entry in an element's local +// reference table. +// +// TODO(mdempsky): Rename this too. +type RelocEnt struct { + Kind RelocKind + Idx Index +} + +// Reserved indices within the meta relocation section. +const ( + PublicRootIdx Index = 0 + PrivateRootIdx Index = 1 +) + +const ( + RelocString RelocKind = iota + RelocMeta + RelocPosBase + RelocPkg + RelocName + RelocType + RelocObj + RelocObjExt + RelocObjDict + RelocBody + + numRelocs = iota +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/support.go b/vendor/golang.org/x/tools/go/internal/pkgbits/support.go new file mode 100644 index 000000000..ad26d3b28 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/support.go @@ -0,0 +1,17 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import "fmt" + +func assert(b bool) { + if !b { + panic("assertion failed") + } +} + +func errorf(format string, args ...interface{}) { + panic(fmt.Errorf(format, args...)) +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go new file mode 100644 index 000000000..5bd51ef71 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go @@ -0,0 +1,113 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pkgbits + +import ( + "fmt" + "strings" +) + +// fmtFrames formats a backtrace for reporting reader/writer desyncs. +func fmtFrames(pcs ...uintptr) []string { + res := make([]string, 0, len(pcs)) + walkFrames(pcs, func(file string, line int, name string, offset uintptr) { + // Trim package from function name. It's just redundant noise. + name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") + + res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) + }) + return res +} + +type frameVisitor func(file string, line int, name string, offset uintptr) + +// SyncMarker is an enum type that represents markers that may be +// written to export data to ensure the reader and writer stay +// synchronized. +type SyncMarker int + +//go:generate stringer -type=SyncMarker -trimprefix=Sync + +const ( + _ SyncMarker = iota + + // Public markers (known to go/types importers). + + // Low-level coding markers. + SyncEOF + SyncBool + SyncInt64 + SyncUint64 + SyncString + SyncValue + SyncVal + SyncRelocs + SyncReloc + SyncUseReloc + + // Higher-level object and type markers. + SyncPublic + SyncPos + SyncPosBase + SyncObject + SyncObject1 + SyncPkg + SyncPkgDef + SyncMethod + SyncType + SyncTypeIdx + SyncTypeParamNames + SyncSignature + SyncParams + SyncParam + SyncCodeObj + SyncSym + SyncLocalIdent + SyncSelector + + // Private markers (only known to cmd/compile). + SyncPrivate + + SyncFuncExt + SyncVarExt + SyncTypeExt + SyncPragma + + SyncExprList + SyncExprs + SyncExpr + SyncExprType + SyncAssign + SyncOp + SyncFuncLit + SyncCompLit + + SyncDecl + SyncFuncBody + SyncOpenScope + SyncCloseScope + SyncCloseAnotherScope + SyncDeclNames + SyncDeclName + + SyncStmts + SyncBlockStmt + SyncIfStmt + SyncForStmt + SyncSwitchStmt + SyncRangeStmt + SyncCaseClause + SyncCommClause + SyncSelectStmt + SyncDecls + SyncLabeledStmt + SyncUseObjLocal + SyncAddLocal + SyncLinkname + SyncStmt1 + SyncStmtsEnd + SyncLabel + SyncOptLabel +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go new file mode 100644 index 000000000..4a5b0ca5f --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go @@ -0,0 +1,89 @@ +// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. + +package pkgbits + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[SyncEOF-1] + _ = x[SyncBool-2] + _ = x[SyncInt64-3] + _ = x[SyncUint64-4] + _ = x[SyncString-5] + _ = x[SyncValue-6] + _ = x[SyncVal-7] + _ = x[SyncRelocs-8] + _ = x[SyncReloc-9] + _ = x[SyncUseReloc-10] + _ = x[SyncPublic-11] + _ = x[SyncPos-12] + _ = x[SyncPosBase-13] + _ = x[SyncObject-14] + _ = x[SyncObject1-15] + _ = x[SyncPkg-16] + _ = x[SyncPkgDef-17] + _ = x[SyncMethod-18] + _ = x[SyncType-19] + _ = x[SyncTypeIdx-20] + _ = x[SyncTypeParamNames-21] + _ = x[SyncSignature-22] + _ = x[SyncParams-23] + _ = x[SyncParam-24] + _ = x[SyncCodeObj-25] + _ = x[SyncSym-26] + _ = x[SyncLocalIdent-27] + _ = x[SyncSelector-28] + _ = x[SyncPrivate-29] + _ = x[SyncFuncExt-30] + _ = x[SyncVarExt-31] + _ = x[SyncTypeExt-32] + _ = x[SyncPragma-33] + _ = x[SyncExprList-34] + _ = x[SyncExprs-35] + _ = x[SyncExpr-36] + _ = x[SyncExprType-37] + _ = x[SyncAssign-38] + _ = x[SyncOp-39] + _ = x[SyncFuncLit-40] + _ = x[SyncCompLit-41] + _ = x[SyncDecl-42] + _ = x[SyncFuncBody-43] + _ = x[SyncOpenScope-44] + _ = x[SyncCloseScope-45] + _ = x[SyncCloseAnotherScope-46] + _ = x[SyncDeclNames-47] + _ = x[SyncDeclName-48] + _ = x[SyncStmts-49] + _ = x[SyncBlockStmt-50] + _ = x[SyncIfStmt-51] + _ = x[SyncForStmt-52] + _ = x[SyncSwitchStmt-53] + _ = x[SyncRangeStmt-54] + _ = x[SyncCaseClause-55] + _ = x[SyncCommClause-56] + _ = x[SyncSelectStmt-57] + _ = x[SyncDecls-58] + _ = x[SyncLabeledStmt-59] + _ = x[SyncUseObjLocal-60] + _ = x[SyncAddLocal-61] + _ = x[SyncLinkname-62] + _ = x[SyncStmt1-63] + _ = x[SyncStmtsEnd-64] + _ = x[SyncLabel-65] + _ = x[SyncOptLabel-66] +} + +const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel" + +var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458} + +func (i SyncMarker) String() string { + i -= 1 + if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { + return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] +} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go index 50533995a..de881562d 100644 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -302,11 +302,12 @@ func (state *golistState) runContainsQueries(response *responseDeduper, queries } dirResponse, err := state.createDriverResponse(pattern) - // If there was an error loading the package, or the package is returned - // with errors, try to load the file as an ad-hoc package. + // If there was an error loading the package, or no packages are returned, + // or the package is returned with errors, try to load the file as an + // ad-hoc package. // Usually the error will appear in a returned package, but may not if we're // in module mode and the ad-hoc is located outside a module. - if err != nil || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && + if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && len(dirResponse.Packages[0].Errors) == 1 { var queryErr error if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go index d859617b7..9e373d64e 100644 --- a/vendor/golang.org/x/tools/internal/imports/fix.go +++ b/vendor/golang.org/x/tools/internal/imports/fix.go @@ -796,7 +796,7 @@ func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchP return getCandidatePkgs(ctx, callback, filename, filePkg, env) } -var RequiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB"} +var RequiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB", "GOWORK"} // ProcessEnv contains environment variables and settings that affect the use of // the go command, the go/build package, etc. @@ -906,7 +906,7 @@ func (e *ProcessEnv) GetResolver() (Resolver, error) { if err := e.init(); err != nil { return nil, err } - if len(e.Env["GOMOD"]) == 0 { + if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 { e.resolver = newGopathResolver(e) return e.resolver, nil } diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go index 2bcf41f5f..46693f243 100644 --- a/vendor/golang.org/x/tools/internal/imports/mod.go +++ b/vendor/golang.org/x/tools/internal/imports/mod.go @@ -70,9 +70,17 @@ func (r *ModuleResolver) init() error { Logf: r.env.Logf, WorkingDir: r.env.WorkingDir, } - vendorEnabled, mainModVendor, err := gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) - if err != nil { - return err + + vendorEnabled := false + var mainModVendor *gocommand.ModuleJSON + + // Module vendor directories are ignored in workspace mode: + // https://go.googlesource.com/proposal/+/master/design/45713-workspace.md + if len(r.env.Env["GOWORK"]) == 0 { + vendorEnabled, mainModVendor, err = gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) + if err != nil { + return err + } } if mainModVendor != nil && vendorEnabled { diff --git a/vendor/google.golang.org/protobuf/AUTHORS b/vendor/google.golang.org/protobuf/AUTHORS deleted file mode 100644 index 2b00ddba0..000000000 --- a/vendor/google.golang.org/protobuf/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 https://tip.golang.org/AUTHORS. diff --git a/vendor/google.golang.org/protobuf/CONTRIBUTORS b/vendor/google.golang.org/protobuf/CONTRIBUTORS deleted file mode 100644 index 1fbd3e976..000000000 --- a/vendor/google.golang.org/protobuf/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 https://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index 179d6e8fc..4921b2d4a 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -17,7 +17,7 @@ import ( "google.golang.org/protobuf/internal/set" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/proto" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" ) @@ -103,7 +103,7 @@ func (d decoder) syntaxError(pos int, f string, x ...interface{}) error { } // unmarshalMessage unmarshals into the given protoreflect.Message. -func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error { +func (d decoder) unmarshalMessage(m protoreflect.Message, checkDelims bool) error { messageDesc := m.Descriptor() if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { return errors.New("no support for proto1 MessageSets") @@ -150,24 +150,24 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error { } // Resolve the field descriptor. - var name pref.Name - var fd pref.FieldDescriptor - var xt pref.ExtensionType + var name protoreflect.Name + var fd protoreflect.FieldDescriptor + var xt protoreflect.ExtensionType var xtErr error var isFieldNumberName bool switch tok.NameKind() { case text.IdentName: - name = pref.Name(tok.IdentName()) + name = protoreflect.Name(tok.IdentName()) fd = fieldDescs.ByTextName(string(name)) case text.TypeName: // Handle extensions only. This code path is not for Any. - xt, xtErr = d.opts.Resolver.FindExtensionByName(pref.FullName(tok.TypeName())) + xt, xtErr = d.opts.Resolver.FindExtensionByName(protoreflect.FullName(tok.TypeName())) case text.FieldNumber: isFieldNumberName = true - num := pref.FieldNumber(tok.FieldNumber()) + num := protoreflect.FieldNumber(tok.FieldNumber()) if !num.IsValid() { return d.newError(tok.Pos(), "invalid field number: %d", num) } @@ -215,7 +215,7 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error { switch { case fd.IsList(): kind := fd.Kind() - if kind != pref.MessageKind && kind != pref.GroupKind && !tok.HasSeparator() { + if kind != protoreflect.MessageKind && kind != protoreflect.GroupKind && !tok.HasSeparator() { return d.syntaxError(tok.Pos(), "missing field separator :") } @@ -232,7 +232,7 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error { default: kind := fd.Kind() - if kind != pref.MessageKind && kind != pref.GroupKind && !tok.HasSeparator() { + if kind != protoreflect.MessageKind && kind != protoreflect.GroupKind && !tok.HasSeparator() { return d.syntaxError(tok.Pos(), "missing field separator :") } @@ -262,11 +262,11 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error { // unmarshalSingular unmarshals a non-repeated field value specified by the // given FieldDescriptor. -func (d decoder) unmarshalSingular(fd pref.FieldDescriptor, m pref.Message) error { - var val pref.Value +func (d decoder) unmarshalSingular(fd protoreflect.FieldDescriptor, m protoreflect.Message) error { + var val protoreflect.Value var err error switch fd.Kind() { - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: val = m.NewField(fd) err = d.unmarshalMessage(val.Message(), true) default: @@ -280,94 +280,94 @@ func (d decoder) unmarshalSingular(fd pref.FieldDescriptor, m pref.Message) erro // unmarshalScalar unmarshals a scalar/enum protoreflect.Value specified by the // given FieldDescriptor. -func (d decoder) unmarshalScalar(fd pref.FieldDescriptor) (pref.Value, error) { +func (d decoder) unmarshalScalar(fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { tok, err := d.Read() if err != nil { - return pref.Value{}, err + return protoreflect.Value{}, err } if tok.Kind() != text.Scalar { - return pref.Value{}, d.unexpectedTokenError(tok) + return protoreflect.Value{}, d.unexpectedTokenError(tok) } kind := fd.Kind() switch kind { - case pref.BoolKind: + case protoreflect.BoolKind: if b, ok := tok.Bool(); ok { - return pref.ValueOfBool(b), nil + return protoreflect.ValueOfBool(b), nil } - case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: if n, ok := tok.Int32(); ok { - return pref.ValueOfInt32(n), nil + return protoreflect.ValueOfInt32(n), nil } - case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: if n, ok := tok.Int64(); ok { - return pref.ValueOfInt64(n), nil + return protoreflect.ValueOfInt64(n), nil } - case pref.Uint32Kind, pref.Fixed32Kind: + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: if n, ok := tok.Uint32(); ok { - return pref.ValueOfUint32(n), nil + return protoreflect.ValueOfUint32(n), nil } - case pref.Uint64Kind, pref.Fixed64Kind: + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: if n, ok := tok.Uint64(); ok { - return pref.ValueOfUint64(n), nil + return protoreflect.ValueOfUint64(n), nil } - case pref.FloatKind: + case protoreflect.FloatKind: if n, ok := tok.Float32(); ok { - return pref.ValueOfFloat32(n), nil + return protoreflect.ValueOfFloat32(n), nil } - case pref.DoubleKind: + case protoreflect.DoubleKind: if n, ok := tok.Float64(); ok { - return pref.ValueOfFloat64(n), nil + return protoreflect.ValueOfFloat64(n), nil } - case pref.StringKind: + case protoreflect.StringKind: if s, ok := tok.String(); ok { if strs.EnforceUTF8(fd) && !utf8.ValidString(s) { - return pref.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8") + return protoreflect.Value{}, d.newError(tok.Pos(), "contains invalid UTF-8") } - return pref.ValueOfString(s), nil + return protoreflect.ValueOfString(s), nil } - case pref.BytesKind: + case protoreflect.BytesKind: if b, ok := tok.String(); ok { - return pref.ValueOfBytes([]byte(b)), nil + return protoreflect.ValueOfBytes([]byte(b)), nil } - case pref.EnumKind: + case protoreflect.EnumKind: if lit, ok := tok.Enum(); ok { // Lookup EnumNumber based on name. - if enumVal := fd.Enum().Values().ByName(pref.Name(lit)); enumVal != nil { - return pref.ValueOfEnum(enumVal.Number()), nil + if enumVal := fd.Enum().Values().ByName(protoreflect.Name(lit)); enumVal != nil { + return protoreflect.ValueOfEnum(enumVal.Number()), nil } } if num, ok := tok.Int32(); ok { - return pref.ValueOfEnum(pref.EnumNumber(num)), nil + return protoreflect.ValueOfEnum(protoreflect.EnumNumber(num)), nil } default: panic(fmt.Sprintf("invalid scalar kind %v", kind)) } - return pref.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString()) + return protoreflect.Value{}, d.newError(tok.Pos(), "invalid value for %v type: %v", kind, tok.RawString()) } // unmarshalList unmarshals into given protoreflect.List. A list value can // either be in [] syntax or simply just a single scalar/message value. -func (d decoder) unmarshalList(fd pref.FieldDescriptor, list pref.List) error { +func (d decoder) unmarshalList(fd protoreflect.FieldDescriptor, list protoreflect.List) error { tok, err := d.Peek() if err != nil { return err } switch fd.Kind() { - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: switch tok.Kind() { case text.ListOpen: d.Read() @@ -441,22 +441,22 @@ func (d decoder) unmarshalList(fd pref.FieldDescriptor, list pref.List) error { // unmarshalMap unmarshals into given protoreflect.Map. A map value is a // textproto message containing {key: , value: }. -func (d decoder) unmarshalMap(fd pref.FieldDescriptor, mmap pref.Map) error { +func (d decoder) unmarshalMap(fd protoreflect.FieldDescriptor, mmap protoreflect.Map) error { // Determine ahead whether map entry is a scalar type or a message type in // order to call the appropriate unmarshalMapValue func inside // unmarshalMapEntry. - var unmarshalMapValue func() (pref.Value, error) + var unmarshalMapValue func() (protoreflect.Value, error) switch fd.MapValue().Kind() { - case pref.MessageKind, pref.GroupKind: - unmarshalMapValue = func() (pref.Value, error) { + case protoreflect.MessageKind, protoreflect.GroupKind: + unmarshalMapValue = func() (protoreflect.Value, error) { pval := mmap.NewValue() if err := d.unmarshalMessage(pval.Message(), true); err != nil { - return pref.Value{}, err + return protoreflect.Value{}, err } return pval, nil } default: - unmarshalMapValue = func() (pref.Value, error) { + unmarshalMapValue = func() (protoreflect.Value, error) { return d.unmarshalScalar(fd.MapValue()) } } @@ -494,9 +494,9 @@ func (d decoder) unmarshalMap(fd pref.FieldDescriptor, mmap pref.Map) error { // unmarshalMap unmarshals into given protoreflect.Map. A map value is a // textproto message containing {key: , value: }. -func (d decoder) unmarshalMapEntry(fd pref.FieldDescriptor, mmap pref.Map, unmarshalMapValue func() (pref.Value, error)) error { - var key pref.MapKey - var pval pref.Value +func (d decoder) unmarshalMapEntry(fd protoreflect.FieldDescriptor, mmap protoreflect.Map, unmarshalMapValue func() (protoreflect.Value, error)) error { + var key protoreflect.MapKey + var pval protoreflect.Value Loop: for { // Read field name. @@ -520,7 +520,7 @@ Loop: return d.unexpectedTokenError(tok) } - switch name := pref.Name(tok.IdentName()); name { + switch name := protoreflect.Name(tok.IdentName()); name { case genid.MapEntry_Key_field_name: if !tok.HasSeparator() { return d.syntaxError(tok.Pos(), "missing field separator :") @@ -535,7 +535,7 @@ Loop: key = val.MapKey() case genid.MapEntry_Value_field_name: - if kind := fd.MapValue().Kind(); (kind != pref.MessageKind) && (kind != pref.GroupKind) { + if kind := fd.MapValue().Kind(); (kind != protoreflect.MessageKind) && (kind != protoreflect.GroupKind) { if !tok.HasSeparator() { return d.syntaxError(tok.Pos(), "missing field separator :") } @@ -561,7 +561,7 @@ Loop: } if !pval.IsValid() { switch fd.MapValue().Kind() { - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: // If value field is not set for message/group types, construct an // empty one as default. pval = mmap.NewValue() @@ -575,7 +575,7 @@ Loop: // unmarshalAny unmarshals an Any textproto. It can either be in expanded form // or non-expanded form. -func (d decoder) unmarshalAny(m pref.Message, checkDelims bool) error { +func (d decoder) unmarshalAny(m protoreflect.Message, checkDelims bool) error { var typeURL string var bValue []byte var seenTypeUrl bool @@ -619,7 +619,7 @@ Loop: return d.syntaxError(tok.Pos(), "missing field separator :") } - switch name := pref.Name(tok.IdentName()); name { + switch name := protoreflect.Name(tok.IdentName()); name { case genid.Any_TypeUrl_field_name: if seenTypeUrl { return d.newError(tok.Pos(), "duplicate %v field", genid.Any_TypeUrl_field_fullname) @@ -686,10 +686,10 @@ Loop: fds := m.Descriptor().Fields() if len(typeURL) > 0 { - m.Set(fds.ByNumber(genid.Any_TypeUrl_field_number), pref.ValueOfString(typeURL)) + m.Set(fds.ByNumber(genid.Any_TypeUrl_field_number), protoreflect.ValueOfString(typeURL)) } if len(bValue) > 0 { - m.Set(fds.ByNumber(genid.Any_Value_field_number), pref.ValueOfBytes(bValue)) + m.Set(fds.ByNumber(genid.Any_Value_field_number), protoreflect.ValueOfBytes(bValue)) } return nil } diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go index 8d5304dc5..ebf6c6528 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go @@ -20,7 +20,6 @@ import ( "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" ) @@ -150,7 +149,7 @@ type encoder struct { } // marshalMessage marshals the given protoreflect.Message. -func (e encoder) marshalMessage(m pref.Message, inclDelims bool) error { +func (e encoder) marshalMessage(m protoreflect.Message, inclDelims bool) error { messageDesc := m.Descriptor() if !flags.ProtoLegacy && messageset.IsMessageSet(messageDesc) { return errors.New("no support for proto1 MessageSets") @@ -190,7 +189,7 @@ func (e encoder) marshalMessage(m pref.Message, inclDelims bool) error { } // marshalField marshals the given field with protoreflect.Value. -func (e encoder) marshalField(name string, val pref.Value, fd pref.FieldDescriptor) error { +func (e encoder) marshalField(name string, val protoreflect.Value, fd protoreflect.FieldDescriptor) error { switch { case fd.IsList(): return e.marshalList(name, val.List(), fd) @@ -204,40 +203,40 @@ func (e encoder) marshalField(name string, val pref.Value, fd pref.FieldDescript // marshalSingular marshals the given non-repeated field value. This includes // all scalar types, enums, messages, and groups. -func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error { +func (e encoder) marshalSingular(val protoreflect.Value, fd protoreflect.FieldDescriptor) error { kind := fd.Kind() switch kind { - case pref.BoolKind: + case protoreflect.BoolKind: e.WriteBool(val.Bool()) - case pref.StringKind: + case protoreflect.StringKind: s := val.String() if !e.opts.allowInvalidUTF8 && strs.EnforceUTF8(fd) && !utf8.ValidString(s) { return errors.InvalidUTF8(string(fd.FullName())) } e.WriteString(s) - case pref.Int32Kind, pref.Int64Kind, - pref.Sint32Kind, pref.Sint64Kind, - pref.Sfixed32Kind, pref.Sfixed64Kind: + case protoreflect.Int32Kind, protoreflect.Int64Kind, + protoreflect.Sint32Kind, protoreflect.Sint64Kind, + protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind: e.WriteInt(val.Int()) - case pref.Uint32Kind, pref.Uint64Kind, - pref.Fixed32Kind, pref.Fixed64Kind: + case protoreflect.Uint32Kind, protoreflect.Uint64Kind, + protoreflect.Fixed32Kind, protoreflect.Fixed64Kind: e.WriteUint(val.Uint()) - case pref.FloatKind: + case protoreflect.FloatKind: // Encoder.WriteFloat handles the special numbers NaN and infinites. e.WriteFloat(val.Float(), 32) - case pref.DoubleKind: + case protoreflect.DoubleKind: // Encoder.WriteFloat handles the special numbers NaN and infinites. e.WriteFloat(val.Float(), 64) - case pref.BytesKind: + case protoreflect.BytesKind: e.WriteString(string(val.Bytes())) - case pref.EnumKind: + case protoreflect.EnumKind: num := val.Enum() if desc := fd.Enum().Values().ByNumber(num); desc != nil { e.WriteLiteral(string(desc.Name())) @@ -246,7 +245,7 @@ func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error e.WriteInt(int64(num)) } - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: return e.marshalMessage(val.Message(), true) default: @@ -256,7 +255,7 @@ func (e encoder) marshalSingular(val pref.Value, fd pref.FieldDescriptor) error } // marshalList marshals the given protoreflect.List as multiple name-value fields. -func (e encoder) marshalList(name string, list pref.List, fd pref.FieldDescriptor) error { +func (e encoder) marshalList(name string, list protoreflect.List, fd protoreflect.FieldDescriptor) error { size := list.Len() for i := 0; i < size; i++ { e.WriteName(name) @@ -268,9 +267,9 @@ func (e encoder) marshalList(name string, list pref.List, fd pref.FieldDescripto } // marshalMap marshals the given protoreflect.Map as multiple name-value fields. -func (e encoder) marshalMap(name string, mmap pref.Map, fd pref.FieldDescriptor) error { +func (e encoder) marshalMap(name string, mmap protoreflect.Map, fd protoreflect.FieldDescriptor) error { var err error - order.RangeEntries(mmap, order.GenericKeyOrder, func(key pref.MapKey, val pref.Value) bool { + order.RangeEntries(mmap, order.GenericKeyOrder, func(key protoreflect.MapKey, val protoreflect.Value) bool { e.WriteName(name) e.StartMessage() defer e.EndMessage() @@ -334,7 +333,7 @@ func (e encoder) marshalUnknown(b []byte) { // marshalAny marshals the given google.protobuf.Any message in expanded form. // It returns true if it was able to marshal, else false. -func (e encoder) marshalAny(any pref.Message) bool { +func (e encoder) marshalAny(any protoreflect.Message) bool { // Construct the embedded message. fds := any.Descriptor().Fields() fdType := fds.ByNumber(genid.Any_TypeUrl_field_number) diff --git a/vendor/google.golang.org/protobuf/encoding/protowire/wire.go b/vendor/google.golang.org/protobuf/encoding/protowire/wire.go index 9c61112f5..ce57f57eb 100644 --- a/vendor/google.golang.org/protobuf/encoding/protowire/wire.go +++ b/vendor/google.golang.org/protobuf/encoding/protowire/wire.go @@ -516,6 +516,7 @@ func EncodeTag(num Number, typ Type) uint64 { } // DecodeZigZag decodes a zig-zag-encoded uint64 as an int64. +// // Input: {…, 5, 3, 1, 0, 2, 4, 6, …} // Output: {…, -3, -2, -1, 0, +1, +2, +3, …} func DecodeZigZag(x uint64) int64 { @@ -523,6 +524,7 @@ func DecodeZigZag(x uint64) int64 { } // EncodeZigZag encodes an int64 as a zig-zag-encoded uint64. +// // Input: {…, -3, -2, -1, 0, +1, +2, +3, …} // Output: {…, 5, 3, 1, 0, 2, 4, 6, …} func EncodeZigZag(x int64) uint64 { @@ -530,6 +532,7 @@ func EncodeZigZag(x int64) uint64 { } // DecodeBool decodes a uint64 as a bool. +// // Input: { 0, 1, 2, …} // Output: {false, true, true, …} func DecodeBool(x uint64) bool { @@ -537,6 +540,7 @@ func DecodeBool(x uint64) bool { } // EncodeBool encodes a bool as a uint64. +// // Input: {false, true} // Output: { 0, 1} func EncodeBool(x bool) uint64 { diff --git a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go index 360c63329..db5248e1b 100644 --- a/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go +++ b/vendor/google.golang.org/protobuf/internal/descfmt/stringer.go @@ -14,7 +14,7 @@ import ( "google.golang.org/protobuf/internal/detrand" "google.golang.org/protobuf/internal/pragma" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type list interface { @@ -30,17 +30,17 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { if isRoot { var name string switch vs.(type) { - case pref.Names: + case protoreflect.Names: name = "Names" - case pref.FieldNumbers: + case protoreflect.FieldNumbers: name = "FieldNumbers" - case pref.FieldRanges: + case protoreflect.FieldRanges: name = "FieldRanges" - case pref.EnumRanges: + case protoreflect.EnumRanges: name = "EnumRanges" - case pref.FileImports: + case protoreflect.FileImports: name = "FileImports" - case pref.Descriptor: + case protoreflect.Descriptor: name = reflect.ValueOf(vs).MethodByName("Get").Type().Out(0).Name() + "s" default: name = reflect.ValueOf(vs).Elem().Type().Name() @@ -50,17 +50,17 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { var ss []string switch vs := vs.(type) { - case pref.Names: + case protoreflect.Names: for i := 0; i < vs.Len(); i++ { ss = append(ss, fmt.Sprint(vs.Get(i))) } return start + joinStrings(ss, false) + end - case pref.FieldNumbers: + case protoreflect.FieldNumbers: for i := 0; i < vs.Len(); i++ { ss = append(ss, fmt.Sprint(vs.Get(i))) } return start + joinStrings(ss, false) + end - case pref.FieldRanges: + case protoreflect.FieldRanges: for i := 0; i < vs.Len(); i++ { r := vs.Get(i) if r[0]+1 == r[1] { @@ -70,7 +70,7 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { } } return start + joinStrings(ss, false) + end - case pref.EnumRanges: + case protoreflect.EnumRanges: for i := 0; i < vs.Len(); i++ { r := vs.Get(i) if r[0] == r[1] { @@ -80,7 +80,7 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { } } return start + joinStrings(ss, false) + end - case pref.FileImports: + case protoreflect.FileImports: for i := 0; i < vs.Len(); i++ { var rs records rs.Append(reflect.ValueOf(vs.Get(i)), "Path", "Package", "IsPublic", "IsWeak") @@ -88,11 +88,11 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { } return start + joinStrings(ss, allowMulti) + end default: - _, isEnumValue := vs.(pref.EnumValueDescriptors) + _, isEnumValue := vs.(protoreflect.EnumValueDescriptors) for i := 0; i < vs.Len(); i++ { m := reflect.ValueOf(vs).MethodByName("Get") v := m.Call([]reflect.Value{reflect.ValueOf(i)})[0].Interface() - ss = append(ss, formatDescOpt(v.(pref.Descriptor), false, allowMulti && !isEnumValue)) + ss = append(ss, formatDescOpt(v.(protoreflect.Descriptor), false, allowMulti && !isEnumValue)) } return start + joinStrings(ss, allowMulti && isEnumValue) + end } @@ -106,20 +106,20 @@ func formatListOpt(vs list, isRoot, allowMulti bool) string { // // Using a list allows us to print the accessors in a sensible order. var descriptorAccessors = map[reflect.Type][]string{ - reflect.TypeOf((*pref.FileDescriptor)(nil)).Elem(): {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"}, - reflect.TypeOf((*pref.MessageDescriptor)(nil)).Elem(): {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"}, - reflect.TypeOf((*pref.FieldDescriptor)(nil)).Elem(): {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "HasPresence", "IsExtension", "IsPacked", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"}, - reflect.TypeOf((*pref.OneofDescriptor)(nil)).Elem(): {"Fields"}, // not directly used; must keep in sync with formatDescOpt - reflect.TypeOf((*pref.EnumDescriptor)(nil)).Elem(): {"Values", "ReservedNames", "ReservedRanges"}, - reflect.TypeOf((*pref.EnumValueDescriptor)(nil)).Elem(): {"Number"}, - reflect.TypeOf((*pref.ServiceDescriptor)(nil)).Elem(): {"Methods"}, - reflect.TypeOf((*pref.MethodDescriptor)(nil)).Elem(): {"Input", "Output", "IsStreamingClient", "IsStreamingServer"}, + reflect.TypeOf((*protoreflect.FileDescriptor)(nil)).Elem(): {"Path", "Package", "Imports", "Messages", "Enums", "Extensions", "Services"}, + reflect.TypeOf((*protoreflect.MessageDescriptor)(nil)).Elem(): {"IsMapEntry", "Fields", "Oneofs", "ReservedNames", "ReservedRanges", "RequiredNumbers", "ExtensionRanges", "Messages", "Enums", "Extensions"}, + reflect.TypeOf((*protoreflect.FieldDescriptor)(nil)).Elem(): {"Number", "Cardinality", "Kind", "HasJSONName", "JSONName", "HasPresence", "IsExtension", "IsPacked", "IsWeak", "IsList", "IsMap", "MapKey", "MapValue", "HasDefault", "Default", "ContainingOneof", "ContainingMessage", "Message", "Enum"}, + reflect.TypeOf((*protoreflect.OneofDescriptor)(nil)).Elem(): {"Fields"}, // not directly used; must keep in sync with formatDescOpt + reflect.TypeOf((*protoreflect.EnumDescriptor)(nil)).Elem(): {"Values", "ReservedNames", "ReservedRanges"}, + reflect.TypeOf((*protoreflect.EnumValueDescriptor)(nil)).Elem(): {"Number"}, + reflect.TypeOf((*protoreflect.ServiceDescriptor)(nil)).Elem(): {"Methods"}, + reflect.TypeOf((*protoreflect.MethodDescriptor)(nil)).Elem(): {"Input", "Output", "IsStreamingClient", "IsStreamingServer"}, } -func FormatDesc(s fmt.State, r rune, t pref.Descriptor) { +func FormatDesc(s fmt.State, r rune, t protoreflect.Descriptor) { io.WriteString(s, formatDescOpt(t, true, r == 'v' && (s.Flag('+') || s.Flag('#')))) } -func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string { +func formatDescOpt(t protoreflect.Descriptor, isRoot, allowMulti bool) string { rv := reflect.ValueOf(t) rt := rv.MethodByName("ProtoType").Type().In(0) @@ -128,7 +128,7 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string { start = rt.Name() + "{" } - _, isFile := t.(pref.FileDescriptor) + _, isFile := t.(protoreflect.FileDescriptor) rs := records{allowMulti: allowMulti} if t.IsPlaceholder() { if isFile { @@ -146,7 +146,7 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string { rs.Append(rv, "Name") } switch t := t.(type) { - case pref.FieldDescriptor: + case protoreflect.FieldDescriptor: for _, s := range descriptorAccessors[rt] { switch s { case "MapKey": @@ -156,9 +156,9 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string { case "MapValue": if v := t.MapValue(); v != nil { switch v.Kind() { - case pref.EnumKind: + case protoreflect.EnumKind: rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Enum().FullName())}) - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: rs.recs = append(rs.recs, [2]string{"MapValue", string(v.Message().FullName())}) default: rs.recs = append(rs.recs, [2]string{"MapValue", v.Kind().String()}) @@ -180,7 +180,7 @@ func formatDescOpt(t pref.Descriptor, isRoot, allowMulti bool) string { rs.Append(rv, s) } } - case pref.OneofDescriptor: + case protoreflect.OneofDescriptor: var ss []string fs := t.Fields() for i := 0; i < fs.Len(); i++ { @@ -216,7 +216,7 @@ func (rs *records) Append(v reflect.Value, accessors ...string) { if !rv.IsValid() { panic(fmt.Sprintf("unknown accessor: %v.%s", v.Type(), a)) } - if _, ok := rv.Interface().(pref.Value); ok { + if _, ok := rv.Interface().(protoreflect.Value); ok { rv = rv.MethodByName("Interface").Call(nil)[0] if !rv.IsNil() { rv = rv.Elem() @@ -250,9 +250,9 @@ func (rs *records) Append(v reflect.Value, accessors ...string) { switch v := v.(type) { case list: s = formatListOpt(v, false, rs.allowMulti) - case pref.FieldDescriptor, pref.OneofDescriptor, pref.EnumValueDescriptor, pref.MethodDescriptor: - s = string(v.(pref.Descriptor).Name()) - case pref.Descriptor: + case protoreflect.FieldDescriptor, protoreflect.OneofDescriptor, protoreflect.EnumValueDescriptor, protoreflect.MethodDescriptor: + s = string(v.(protoreflect.Descriptor).Name()) + case protoreflect.Descriptor: s = string(v.FullName()) case string: s = strconv.Quote(v) diff --git a/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go b/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go index fdd9b13f2..328dc733b 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/defval/default.go @@ -15,8 +15,8 @@ import ( "strconv" ptext "google.golang.org/protobuf/internal/encoding/text" - errors "google.golang.org/protobuf/internal/errors" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/internal/errors" + "google.golang.org/protobuf/reflect/protoreflect" ) // Format is the serialization format used to represent the default value. @@ -35,56 +35,56 @@ const ( // Unmarshal deserializes the default string s according to the given kind k. // When k is an enum, a list of enum value descriptors must be provided. -func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) (pref.Value, pref.EnumValueDescriptor, error) { +func Unmarshal(s string, k protoreflect.Kind, evs protoreflect.EnumValueDescriptors, f Format) (protoreflect.Value, protoreflect.EnumValueDescriptor, error) { switch k { - case pref.BoolKind: + case protoreflect.BoolKind: if f == GoTag { switch s { case "1": - return pref.ValueOfBool(true), nil, nil + return protoreflect.ValueOfBool(true), nil, nil case "0": - return pref.ValueOfBool(false), nil, nil + return protoreflect.ValueOfBool(false), nil, nil } } else { switch s { case "true": - return pref.ValueOfBool(true), nil, nil + return protoreflect.ValueOfBool(true), nil, nil case "false": - return pref.ValueOfBool(false), nil, nil + return protoreflect.ValueOfBool(false), nil, nil } } - case pref.EnumKind: + case protoreflect.EnumKind: if f == GoTag { // Go tags use the numeric form of the enum value. if n, err := strconv.ParseInt(s, 10, 32); err == nil { - if ev := evs.ByNumber(pref.EnumNumber(n)); ev != nil { - return pref.ValueOfEnum(ev.Number()), ev, nil + if ev := evs.ByNumber(protoreflect.EnumNumber(n)); ev != nil { + return protoreflect.ValueOfEnum(ev.Number()), ev, nil } } } else { // Descriptor default_value use the enum identifier. - ev := evs.ByName(pref.Name(s)) + ev := evs.ByName(protoreflect.Name(s)) if ev != nil { - return pref.ValueOfEnum(ev.Number()), ev, nil + return protoreflect.ValueOfEnum(ev.Number()), ev, nil } } - case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: if v, err := strconv.ParseInt(s, 10, 32); err == nil { - return pref.ValueOfInt32(int32(v)), nil, nil + return protoreflect.ValueOfInt32(int32(v)), nil, nil } - case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: if v, err := strconv.ParseInt(s, 10, 64); err == nil { - return pref.ValueOfInt64(int64(v)), nil, nil + return protoreflect.ValueOfInt64(int64(v)), nil, nil } - case pref.Uint32Kind, pref.Fixed32Kind: + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: if v, err := strconv.ParseUint(s, 10, 32); err == nil { - return pref.ValueOfUint32(uint32(v)), nil, nil + return protoreflect.ValueOfUint32(uint32(v)), nil, nil } - case pref.Uint64Kind, pref.Fixed64Kind: + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: if v, err := strconv.ParseUint(s, 10, 64); err == nil { - return pref.ValueOfUint64(uint64(v)), nil, nil + return protoreflect.ValueOfUint64(uint64(v)), nil, nil } - case pref.FloatKind, pref.DoubleKind: + case protoreflect.FloatKind, protoreflect.DoubleKind: var v float64 var err error switch s { @@ -98,29 +98,29 @@ func Unmarshal(s string, k pref.Kind, evs pref.EnumValueDescriptors, f Format) ( v, err = strconv.ParseFloat(s, 64) } if err == nil { - if k == pref.FloatKind { - return pref.ValueOfFloat32(float32(v)), nil, nil + if k == protoreflect.FloatKind { + return protoreflect.ValueOfFloat32(float32(v)), nil, nil } else { - return pref.ValueOfFloat64(float64(v)), nil, nil + return protoreflect.ValueOfFloat64(float64(v)), nil, nil } } - case pref.StringKind: + case protoreflect.StringKind: // String values are already unescaped and can be used as is. - return pref.ValueOfString(s), nil, nil - case pref.BytesKind: + return protoreflect.ValueOfString(s), nil, nil + case protoreflect.BytesKind: if b, ok := unmarshalBytes(s); ok { - return pref.ValueOfBytes(b), nil, nil + return protoreflect.ValueOfBytes(b), nil, nil } } - return pref.Value{}, nil, errors.New("could not parse value for %v: %q", k, s) + return protoreflect.Value{}, nil, errors.New("could not parse value for %v: %q", k, s) } // Marshal serializes v as the default string according to the given kind k. // When specifying the Descriptor format for an enum kind, the associated // enum value descriptor must be provided. -func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) (string, error) { +func Marshal(v protoreflect.Value, ev protoreflect.EnumValueDescriptor, k protoreflect.Kind, f Format) (string, error) { switch k { - case pref.BoolKind: + case protoreflect.BoolKind: if f == GoTag { if v.Bool() { return "1", nil @@ -134,17 +134,17 @@ func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) ( return "false", nil } } - case pref.EnumKind: + case protoreflect.EnumKind: if f == GoTag { return strconv.FormatInt(int64(v.Enum()), 10), nil } else { return string(ev.Name()), nil } - case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind, pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: return strconv.FormatInt(v.Int(), 10), nil - case pref.Uint32Kind, pref.Fixed32Kind, pref.Uint64Kind, pref.Fixed64Kind: + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: return strconv.FormatUint(v.Uint(), 10), nil - case pref.FloatKind, pref.DoubleKind: + case protoreflect.FloatKind, protoreflect.DoubleKind: f := v.Float() switch { case math.IsInf(f, -1): @@ -154,16 +154,16 @@ func Marshal(v pref.Value, ev pref.EnumValueDescriptor, k pref.Kind, f Format) ( case math.IsNaN(f): return "nan", nil default: - if k == pref.FloatKind { + if k == protoreflect.FloatKind { return strconv.FormatFloat(f, 'g', -1, 32), nil } else { return strconv.FormatFloat(f, 'g', -1, 64), nil } } - case pref.StringKind: + case protoreflect.StringKind: // String values are serialized as is without any escaping. return v.String(), nil - case pref.BytesKind: + case protoreflect.BytesKind: if s, ok := marshalBytes(v.Bytes()); ok { return s, nil } diff --git a/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go b/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go index c1866f3c1..a6693f0a2 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) // The MessageSet wire format is equivalent to a message defined as follows, @@ -33,6 +33,7 @@ const ( // ExtensionName is the field name for extensions of MessageSet. // // A valid MessageSet extension must be of the form: +// // message MyMessage { // extend proto2.bridge.MessageSet { // optional MyMessage message_set_extension = 1234; @@ -42,13 +43,13 @@ const ( const ExtensionName = "message_set_extension" // IsMessageSet returns whether the message uses the MessageSet wire format. -func IsMessageSet(md pref.MessageDescriptor) bool { +func IsMessageSet(md protoreflect.MessageDescriptor) bool { xmd, ok := md.(interface{ IsMessageSet() bool }) return ok && xmd.IsMessageSet() } // IsMessageSetExtension reports this field properly extends a MessageSet. -func IsMessageSetExtension(fd pref.FieldDescriptor) bool { +func IsMessageSetExtension(fd protoreflect.FieldDescriptor) bool { switch { case fd.Name() != ExtensionName: return false diff --git a/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go b/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go index 38f1931c6..373d20837 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go @@ -11,10 +11,10 @@ import ( "strconv" "strings" - defval "google.golang.org/protobuf/internal/encoding/defval" - fdesc "google.golang.org/protobuf/internal/filedesc" + "google.golang.org/protobuf/internal/encoding/defval" + "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/strs" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) var byteType = reflect.TypeOf(byte(0)) @@ -29,9 +29,9 @@ var byteType = reflect.TypeOf(byte(0)) // This does not populate the Enum or Message (except for weak message). // // This function is a best effort attempt; parsing errors are ignored. -func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) pref.FieldDescriptor { - f := new(fdesc.Field) - f.L0.ParentFile = fdesc.SurrogateProto2 +func Unmarshal(tag string, goType reflect.Type, evs protoreflect.EnumValueDescriptors) protoreflect.FieldDescriptor { + f := new(filedesc.Field) + f.L0.ParentFile = filedesc.SurrogateProto2 for len(tag) > 0 { i := strings.IndexByte(tag, ',') if i < 0 { @@ -39,68 +39,68 @@ func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) p } switch s := tag[:i]; { case strings.HasPrefix(s, "name="): - f.L0.FullName = pref.FullName(s[len("name="):]) + f.L0.FullName = protoreflect.FullName(s[len("name="):]) case strings.Trim(s, "0123456789") == "": n, _ := strconv.ParseUint(s, 10, 32) - f.L1.Number = pref.FieldNumber(n) + f.L1.Number = protoreflect.FieldNumber(n) case s == "opt": - f.L1.Cardinality = pref.Optional + f.L1.Cardinality = protoreflect.Optional case s == "req": - f.L1.Cardinality = pref.Required + f.L1.Cardinality = protoreflect.Required case s == "rep": - f.L1.Cardinality = pref.Repeated + f.L1.Cardinality = protoreflect.Repeated case s == "varint": switch goType.Kind() { case reflect.Bool: - f.L1.Kind = pref.BoolKind + f.L1.Kind = protoreflect.BoolKind case reflect.Int32: - f.L1.Kind = pref.Int32Kind + f.L1.Kind = protoreflect.Int32Kind case reflect.Int64: - f.L1.Kind = pref.Int64Kind + f.L1.Kind = protoreflect.Int64Kind case reflect.Uint32: - f.L1.Kind = pref.Uint32Kind + f.L1.Kind = protoreflect.Uint32Kind case reflect.Uint64: - f.L1.Kind = pref.Uint64Kind + f.L1.Kind = protoreflect.Uint64Kind } case s == "zigzag32": if goType.Kind() == reflect.Int32 { - f.L1.Kind = pref.Sint32Kind + f.L1.Kind = protoreflect.Sint32Kind } case s == "zigzag64": if goType.Kind() == reflect.Int64 { - f.L1.Kind = pref.Sint64Kind + f.L1.Kind = protoreflect.Sint64Kind } case s == "fixed32": switch goType.Kind() { case reflect.Int32: - f.L1.Kind = pref.Sfixed32Kind + f.L1.Kind = protoreflect.Sfixed32Kind case reflect.Uint32: - f.L1.Kind = pref.Fixed32Kind + f.L1.Kind = protoreflect.Fixed32Kind case reflect.Float32: - f.L1.Kind = pref.FloatKind + f.L1.Kind = protoreflect.FloatKind } case s == "fixed64": switch goType.Kind() { case reflect.Int64: - f.L1.Kind = pref.Sfixed64Kind + f.L1.Kind = protoreflect.Sfixed64Kind case reflect.Uint64: - f.L1.Kind = pref.Fixed64Kind + f.L1.Kind = protoreflect.Fixed64Kind case reflect.Float64: - f.L1.Kind = pref.DoubleKind + f.L1.Kind = protoreflect.DoubleKind } case s == "bytes": switch { case goType.Kind() == reflect.String: - f.L1.Kind = pref.StringKind + f.L1.Kind = protoreflect.StringKind case goType.Kind() == reflect.Slice && goType.Elem() == byteType: - f.L1.Kind = pref.BytesKind + f.L1.Kind = protoreflect.BytesKind default: - f.L1.Kind = pref.MessageKind + f.L1.Kind = protoreflect.MessageKind } case s == "group": - f.L1.Kind = pref.GroupKind + f.L1.Kind = protoreflect.GroupKind case strings.HasPrefix(s, "enum="): - f.L1.Kind = pref.EnumKind + f.L1.Kind = protoreflect.EnumKind case strings.HasPrefix(s, "json="): jsonName := s[len("json="):] if jsonName != strs.JSONCamelCase(string(f.L0.FullName.Name())) { @@ -111,23 +111,23 @@ func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) p f.L1.IsPacked = true case strings.HasPrefix(s, "weak="): f.L1.IsWeak = true - f.L1.Message = fdesc.PlaceholderMessage(pref.FullName(s[len("weak="):])) + f.L1.Message = filedesc.PlaceholderMessage(protoreflect.FullName(s[len("weak="):])) case strings.HasPrefix(s, "def="): // The default tag is special in that everything afterwards is the // default regardless of the presence of commas. s, i = tag[len("def="):], len(tag) v, ev, _ := defval.Unmarshal(s, f.L1.Kind, evs, defval.GoTag) - f.L1.Default = fdesc.DefaultValue(v, ev) + f.L1.Default = filedesc.DefaultValue(v, ev) case s == "proto3": - f.L0.ParentFile = fdesc.SurrogateProto3 + f.L0.ParentFile = filedesc.SurrogateProto3 } tag = strings.TrimPrefix(tag[i:], ",") } // The generator uses the group message name instead of the field name. // We obtain the real field name by lowercasing the group name. - if f.L1.Kind == pref.GroupKind { - f.L0.FullName = pref.FullName(strings.ToLower(string(f.L0.FullName))) + if f.L1.Kind == protoreflect.GroupKind { + f.L0.FullName = protoreflect.FullName(strings.ToLower(string(f.L0.FullName))) } return f } @@ -140,38 +140,38 @@ func Unmarshal(tag string, goType reflect.Type, evs pref.EnumValueDescriptors) p // Depending on the context on how Marshal is called, there are different ways // through which that information is determined. As such it is the caller's // responsibility to provide a function to obtain that information. -func Marshal(fd pref.FieldDescriptor, enumName string) string { +func Marshal(fd protoreflect.FieldDescriptor, enumName string) string { var tag []string switch fd.Kind() { - case pref.BoolKind, pref.EnumKind, pref.Int32Kind, pref.Uint32Kind, pref.Int64Kind, pref.Uint64Kind: + case protoreflect.BoolKind, protoreflect.EnumKind, protoreflect.Int32Kind, protoreflect.Uint32Kind, protoreflect.Int64Kind, protoreflect.Uint64Kind: tag = append(tag, "varint") - case pref.Sint32Kind: + case protoreflect.Sint32Kind: tag = append(tag, "zigzag32") - case pref.Sint64Kind: + case protoreflect.Sint64Kind: tag = append(tag, "zigzag64") - case pref.Sfixed32Kind, pref.Fixed32Kind, pref.FloatKind: + case protoreflect.Sfixed32Kind, protoreflect.Fixed32Kind, protoreflect.FloatKind: tag = append(tag, "fixed32") - case pref.Sfixed64Kind, pref.Fixed64Kind, pref.DoubleKind: + case protoreflect.Sfixed64Kind, protoreflect.Fixed64Kind, protoreflect.DoubleKind: tag = append(tag, "fixed64") - case pref.StringKind, pref.BytesKind, pref.MessageKind: + case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind: tag = append(tag, "bytes") - case pref.GroupKind: + case protoreflect.GroupKind: tag = append(tag, "group") } tag = append(tag, strconv.Itoa(int(fd.Number()))) switch fd.Cardinality() { - case pref.Optional: + case protoreflect.Optional: tag = append(tag, "opt") - case pref.Required: + case protoreflect.Required: tag = append(tag, "req") - case pref.Repeated: + case protoreflect.Repeated: tag = append(tag, "rep") } if fd.IsPacked() { tag = append(tag, "packed") } name := string(fd.Name()) - if fd.Kind() == pref.GroupKind { + if fd.Kind() == protoreflect.GroupKind { // The name of the FieldDescriptor for a group field is // lowercased. To find the original capitalization, we // look in the field's MessageType. @@ -189,10 +189,10 @@ func Marshal(fd pref.FieldDescriptor, enumName string) string { // The previous implementation does not tag extension fields as proto3, // even when the field is defined in a proto3 file. Match that behavior // for consistency. - if fd.Syntax() == pref.Proto3 && !fd.IsExtension() { + if fd.Syntax() == protoreflect.Proto3 && !fd.IsExtension() { tag = append(tag, "proto3") } - if fd.Kind() == pref.EnumKind && enumName != "" { + if fd.Kind() == protoreflect.EnumKind && enumName != "" { tag = append(tag, "enum="+enumName) } if fd.ContainingOneof() != nil { diff --git a/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go b/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go index 37803773f..427c62d03 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/text/decode.go @@ -8,7 +8,6 @@ import ( "bytes" "fmt" "io" - "regexp" "strconv" "unicode/utf8" @@ -421,7 +420,7 @@ func (d *Decoder) parseFieldName() (tok Token, err error) { return Token{}, d.newSyntaxError("invalid field number: %s", d.in[:num.size]) } - return Token{}, d.newSyntaxError("invalid field name: %s", errRegexp.Find(d.in)) + return Token{}, d.newSyntaxError("invalid field name: %s", errId(d.in)) } // parseTypeName parses Any type URL or extension field name. The name is @@ -571,7 +570,7 @@ func (d *Decoder) parseScalar() (Token, error) { return tok, nil } - return Token{}, d.newSyntaxError("invalid scalar value: %s", errRegexp.Find(d.in)) + return Token{}, d.newSyntaxError("invalid scalar value: %s", errId(d.in)) } // parseLiteralValue parses a literal value. A literal value is used for @@ -653,8 +652,29 @@ func consume(b []byte, n int) []byte { return b } -// Any sequence that looks like a non-delimiter (for error reporting). -var errRegexp = regexp.MustCompile(`^([-+._a-zA-Z0-9\/]+|.)`) +// errId extracts a byte sequence that looks like an invalid ID +// (for the purposes of error reporting). +func errId(seq []byte) []byte { + const maxLen = 32 + for i := 0; i < len(seq); { + if i > maxLen { + return append(seq[:i:i], "…"...) + } + r, size := utf8.DecodeRune(seq[i:]) + if r > utf8.RuneSelf || (r != '/' && isDelim(byte(r))) { + if i == 0 { + // Either the first byte is invalid UTF-8 or a + // delimiter, or the first rune is non-ASCII. + // Return it as-is. + i = size + } + return seq[:i:i] + } + i += size + } + // No delimiter found. + return seq +} // isDelim returns true if given byte is a delimiter character. func isDelim(c byte) bool { diff --git a/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go b/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go index f2d90b789..81a5d8c86 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go @@ -50,8 +50,10 @@ type number struct { // parseNumber constructs a number object from given input. It allows for the // following patterns: -// integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*) -// float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?) +// +// integer: ^-?([1-9][0-9]*|0[xX][0-9a-fA-F]+|0[0-7]*) +// float: ^-?((0|[1-9][0-9]*)?([.][0-9]*)?([eE][+-]?[0-9]+)?[fF]?) +// // It also returns the number of parsed bytes for the given number, 0 if it is // not a number. func parseNumber(input []byte) number { diff --git a/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go b/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go index 0ce8d6fb8..7ae6c2a3c 100644 --- a/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go +++ b/vendor/google.golang.org/protobuf/internal/encoding/text/doc.go @@ -24,6 +24,6 @@ // the Go implementation should as well. // // The text format is almost a superset of JSON except: -// * message keys are not quoted strings, but identifiers -// * the top-level value must be a message without the delimiters +// - message keys are not quoted strings, but identifiers +// - the top-level value must be a message without the delimiters package text diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/build.go b/vendor/google.golang.org/protobuf/internal/filedesc/build.go index b293b6947..7cac1c190 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/build.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/build.go @@ -12,8 +12,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/reflect/protoreflect" - pref "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/reflect/protoregistry" ) // Builder construct a protoreflect.FileDescriptor from the raw descriptor. @@ -38,7 +37,7 @@ type Builder struct { // TypeResolver resolves extension field types for descriptor options. // If nil, it uses protoregistry.GlobalTypes. TypeResolver interface { - preg.ExtensionTypeResolver + protoregistry.ExtensionTypeResolver } // FileRegistry is use to lookup file, enum, and message dependencies. @@ -46,8 +45,8 @@ type Builder struct { // If nil, it uses protoregistry.GlobalFiles. FileRegistry interface { FindFileByPath(string) (protoreflect.FileDescriptor, error) - FindDescriptorByName(pref.FullName) (pref.Descriptor, error) - RegisterFile(pref.FileDescriptor) error + FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error) + RegisterFile(protoreflect.FileDescriptor) error } } @@ -55,8 +54,8 @@ type Builder struct { // If so, it permits looking up an enum or message dependency based on the // sub-list and element index into filetype.Builder.DependencyIndexes. type resolverByIndex interface { - FindEnumByIndex(int32, int32, []Enum, []Message) pref.EnumDescriptor - FindMessageByIndex(int32, int32, []Enum, []Message) pref.MessageDescriptor + FindEnumByIndex(int32, int32, []Enum, []Message) protoreflect.EnumDescriptor + FindMessageByIndex(int32, int32, []Enum, []Message) protoreflect.MessageDescriptor } // Indexes of each sub-list in filetype.Builder.DependencyIndexes. @@ -70,7 +69,7 @@ const ( // Out is the output of the Builder. type Out struct { - File pref.FileDescriptor + File protoreflect.FileDescriptor // Enums is all enum descriptors in "flattened ordering". Enums []Enum @@ -97,10 +96,10 @@ func (db Builder) Build() (out Out) { // Initialize resolvers and registries if unpopulated. if db.TypeResolver == nil { - db.TypeResolver = preg.GlobalTypes + db.TypeResolver = protoregistry.GlobalTypes } if db.FileRegistry == nil { - db.FileRegistry = preg.GlobalFiles + db.FileRegistry = protoregistry.GlobalFiles } fd := newRawFile(db) diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go index 98ab142ae..7c3689bae 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go @@ -17,7 +17,7 @@ import ( "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/strs" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" ) @@ -43,9 +43,9 @@ type ( L2 *FileL2 } FileL1 struct { - Syntax pref.Syntax + Syntax protoreflect.Syntax Path string - Package pref.FullName + Package protoreflect.FullName Enums Enums Messages Messages @@ -53,36 +53,36 @@ type ( Services Services } FileL2 struct { - Options func() pref.ProtoMessage + Options func() protoreflect.ProtoMessage Imports FileImports Locations SourceLocations } ) -func (fd *File) ParentFile() pref.FileDescriptor { return fd } -func (fd *File) Parent() pref.Descriptor { return nil } -func (fd *File) Index() int { return 0 } -func (fd *File) Syntax() pref.Syntax { return fd.L1.Syntax } -func (fd *File) Name() pref.Name { return fd.L1.Package.Name() } -func (fd *File) FullName() pref.FullName { return fd.L1.Package } -func (fd *File) IsPlaceholder() bool { return false } -func (fd *File) Options() pref.ProtoMessage { +func (fd *File) ParentFile() protoreflect.FileDescriptor { return fd } +func (fd *File) Parent() protoreflect.Descriptor { return nil } +func (fd *File) Index() int { return 0 } +func (fd *File) Syntax() protoreflect.Syntax { return fd.L1.Syntax } +func (fd *File) Name() protoreflect.Name { return fd.L1.Package.Name() } +func (fd *File) FullName() protoreflect.FullName { return fd.L1.Package } +func (fd *File) IsPlaceholder() bool { return false } +func (fd *File) Options() protoreflect.ProtoMessage { if f := fd.lazyInit().Options; f != nil { return f() } return descopts.File } -func (fd *File) Path() string { return fd.L1.Path } -func (fd *File) Package() pref.FullName { return fd.L1.Package } -func (fd *File) Imports() pref.FileImports { return &fd.lazyInit().Imports } -func (fd *File) Enums() pref.EnumDescriptors { return &fd.L1.Enums } -func (fd *File) Messages() pref.MessageDescriptors { return &fd.L1.Messages } -func (fd *File) Extensions() pref.ExtensionDescriptors { return &fd.L1.Extensions } -func (fd *File) Services() pref.ServiceDescriptors { return &fd.L1.Services } -func (fd *File) SourceLocations() pref.SourceLocations { return &fd.lazyInit().Locations } -func (fd *File) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) } -func (fd *File) ProtoType(pref.FileDescriptor) {} -func (fd *File) ProtoInternal(pragma.DoNotImplement) {} +func (fd *File) Path() string { return fd.L1.Path } +func (fd *File) Package() protoreflect.FullName { return fd.L1.Package } +func (fd *File) Imports() protoreflect.FileImports { return &fd.lazyInit().Imports } +func (fd *File) Enums() protoreflect.EnumDescriptors { return &fd.L1.Enums } +func (fd *File) Messages() protoreflect.MessageDescriptors { return &fd.L1.Messages } +func (fd *File) Extensions() protoreflect.ExtensionDescriptors { return &fd.L1.Extensions } +func (fd *File) Services() protoreflect.ServiceDescriptors { return &fd.L1.Services } +func (fd *File) SourceLocations() protoreflect.SourceLocations { return &fd.lazyInit().Locations } +func (fd *File) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) } +func (fd *File) ProtoType(protoreflect.FileDescriptor) {} +func (fd *File) ProtoInternal(pragma.DoNotImplement) {} func (fd *File) lazyInit() *FileL2 { if atomic.LoadUint32(&fd.once) == 0 { @@ -119,7 +119,7 @@ type ( eagerValues bool // controls whether EnumL2.Values is already populated } EnumL2 struct { - Options func() pref.ProtoMessage + Options func() protoreflect.ProtoMessage Values EnumValues ReservedNames Names ReservedRanges EnumRanges @@ -130,41 +130,41 @@ type ( L1 EnumValueL1 } EnumValueL1 struct { - Options func() pref.ProtoMessage - Number pref.EnumNumber + Options func() protoreflect.ProtoMessage + Number protoreflect.EnumNumber } ) -func (ed *Enum) Options() pref.ProtoMessage { +func (ed *Enum) Options() protoreflect.ProtoMessage { if f := ed.lazyInit().Options; f != nil { return f() } return descopts.Enum } -func (ed *Enum) Values() pref.EnumValueDescriptors { +func (ed *Enum) Values() protoreflect.EnumValueDescriptors { if ed.L1.eagerValues { return &ed.L2.Values } return &ed.lazyInit().Values } -func (ed *Enum) ReservedNames() pref.Names { return &ed.lazyInit().ReservedNames } -func (ed *Enum) ReservedRanges() pref.EnumRanges { return &ed.lazyInit().ReservedRanges } -func (ed *Enum) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) } -func (ed *Enum) ProtoType(pref.EnumDescriptor) {} +func (ed *Enum) ReservedNames() protoreflect.Names { return &ed.lazyInit().ReservedNames } +func (ed *Enum) ReservedRanges() protoreflect.EnumRanges { return &ed.lazyInit().ReservedRanges } +func (ed *Enum) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) } +func (ed *Enum) ProtoType(protoreflect.EnumDescriptor) {} func (ed *Enum) lazyInit() *EnumL2 { ed.L0.ParentFile.lazyInit() // implicitly initializes L2 return ed.L2 } -func (ed *EnumValue) Options() pref.ProtoMessage { +func (ed *EnumValue) Options() protoreflect.ProtoMessage { if f := ed.L1.Options; f != nil { return f() } return descopts.EnumValue } -func (ed *EnumValue) Number() pref.EnumNumber { return ed.L1.Number } -func (ed *EnumValue) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) } -func (ed *EnumValue) ProtoType(pref.EnumValueDescriptor) {} +func (ed *EnumValue) Number() protoreflect.EnumNumber { return ed.L1.Number } +func (ed *EnumValue) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, ed) } +func (ed *EnumValue) ProtoType(protoreflect.EnumValueDescriptor) {} type ( Message struct { @@ -180,14 +180,14 @@ type ( IsMessageSet bool // promoted from google.protobuf.MessageOptions } MessageL2 struct { - Options func() pref.ProtoMessage + Options func() protoreflect.ProtoMessage Fields Fields Oneofs Oneofs ReservedNames Names ReservedRanges FieldRanges RequiredNumbers FieldNumbers // must be consistent with Fields.Cardinality ExtensionRanges FieldRanges - ExtensionRangeOptions []func() pref.ProtoMessage // must be same length as ExtensionRanges + ExtensionRangeOptions []func() protoreflect.ProtoMessage // must be same length as ExtensionRanges } Field struct { @@ -195,10 +195,10 @@ type ( L1 FieldL1 } FieldL1 struct { - Options func() pref.ProtoMessage - Number pref.FieldNumber - Cardinality pref.Cardinality // must be consistent with Message.RequiredNumbers - Kind pref.Kind + Options func() protoreflect.ProtoMessage + Number protoreflect.FieldNumber + Cardinality protoreflect.Cardinality // must be consistent with Message.RequiredNumbers + Kind protoreflect.Kind StringName stringName IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto IsWeak bool // promoted from google.protobuf.FieldOptions @@ -207,9 +207,9 @@ type ( HasEnforceUTF8 bool // promoted from google.protobuf.FieldOptions EnforceUTF8 bool // promoted from google.protobuf.FieldOptions Default defaultValue - ContainingOneof pref.OneofDescriptor // must be consistent with Message.Oneofs.Fields - Enum pref.EnumDescriptor - Message pref.MessageDescriptor + ContainingOneof protoreflect.OneofDescriptor // must be consistent with Message.Oneofs.Fields + Enum protoreflect.EnumDescriptor + Message protoreflect.MessageDescriptor } Oneof struct { @@ -217,35 +217,35 @@ type ( L1 OneofL1 } OneofL1 struct { - Options func() pref.ProtoMessage + Options func() protoreflect.ProtoMessage Fields OneofFields // must be consistent with Message.Fields.ContainingOneof } ) -func (md *Message) Options() pref.ProtoMessage { +func (md *Message) Options() protoreflect.ProtoMessage { if f := md.lazyInit().Options; f != nil { return f() } return descopts.Message } -func (md *Message) IsMapEntry() bool { return md.L1.IsMapEntry } -func (md *Message) Fields() pref.FieldDescriptors { return &md.lazyInit().Fields } -func (md *Message) Oneofs() pref.OneofDescriptors { return &md.lazyInit().Oneofs } -func (md *Message) ReservedNames() pref.Names { return &md.lazyInit().ReservedNames } -func (md *Message) ReservedRanges() pref.FieldRanges { return &md.lazyInit().ReservedRanges } -func (md *Message) RequiredNumbers() pref.FieldNumbers { return &md.lazyInit().RequiredNumbers } -func (md *Message) ExtensionRanges() pref.FieldRanges { return &md.lazyInit().ExtensionRanges } -func (md *Message) ExtensionRangeOptions(i int) pref.ProtoMessage { +func (md *Message) IsMapEntry() bool { return md.L1.IsMapEntry } +func (md *Message) Fields() protoreflect.FieldDescriptors { return &md.lazyInit().Fields } +func (md *Message) Oneofs() protoreflect.OneofDescriptors { return &md.lazyInit().Oneofs } +func (md *Message) ReservedNames() protoreflect.Names { return &md.lazyInit().ReservedNames } +func (md *Message) ReservedRanges() protoreflect.FieldRanges { return &md.lazyInit().ReservedRanges } +func (md *Message) RequiredNumbers() protoreflect.FieldNumbers { return &md.lazyInit().RequiredNumbers } +func (md *Message) ExtensionRanges() protoreflect.FieldRanges { return &md.lazyInit().ExtensionRanges } +func (md *Message) ExtensionRangeOptions(i int) protoreflect.ProtoMessage { if f := md.lazyInit().ExtensionRangeOptions[i]; f != nil { return f() } return descopts.ExtensionRange } -func (md *Message) Enums() pref.EnumDescriptors { return &md.L1.Enums } -func (md *Message) Messages() pref.MessageDescriptors { return &md.L1.Messages } -func (md *Message) Extensions() pref.ExtensionDescriptors { return &md.L1.Extensions } -func (md *Message) ProtoType(pref.MessageDescriptor) {} -func (md *Message) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) } +func (md *Message) Enums() protoreflect.EnumDescriptors { return &md.L1.Enums } +func (md *Message) Messages() protoreflect.MessageDescriptors { return &md.L1.Messages } +func (md *Message) Extensions() protoreflect.ExtensionDescriptors { return &md.L1.Extensions } +func (md *Message) ProtoType(protoreflect.MessageDescriptor) {} +func (md *Message) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) } func (md *Message) lazyInit() *MessageL2 { md.L0.ParentFile.lazyInit() // implicitly initializes L2 return md.L2 @@ -260,28 +260,28 @@ func (md *Message) IsMessageSet() bool { return md.L1.IsMessageSet } -func (fd *Field) Options() pref.ProtoMessage { +func (fd *Field) Options() protoreflect.ProtoMessage { if f := fd.L1.Options; f != nil { return f() } return descopts.Field } -func (fd *Field) Number() pref.FieldNumber { return fd.L1.Number } -func (fd *Field) Cardinality() pref.Cardinality { return fd.L1.Cardinality } -func (fd *Field) Kind() pref.Kind { return fd.L1.Kind } -func (fd *Field) HasJSONName() bool { return fd.L1.StringName.hasJSON } -func (fd *Field) JSONName() string { return fd.L1.StringName.getJSON(fd) } -func (fd *Field) TextName() string { return fd.L1.StringName.getText(fd) } +func (fd *Field) Number() protoreflect.FieldNumber { return fd.L1.Number } +func (fd *Field) Cardinality() protoreflect.Cardinality { return fd.L1.Cardinality } +func (fd *Field) Kind() protoreflect.Kind { return fd.L1.Kind } +func (fd *Field) HasJSONName() bool { return fd.L1.StringName.hasJSON } +func (fd *Field) JSONName() string { return fd.L1.StringName.getJSON(fd) } +func (fd *Field) TextName() string { return fd.L1.StringName.getText(fd) } func (fd *Field) HasPresence() bool { - return fd.L1.Cardinality != pref.Repeated && (fd.L0.ParentFile.L1.Syntax == pref.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil) + return fd.L1.Cardinality != protoreflect.Repeated && (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 || fd.L1.Message != nil || fd.L1.ContainingOneof != nil) } func (fd *Field) HasOptionalKeyword() bool { - return (fd.L0.ParentFile.L1.Syntax == pref.Proto2 && fd.L1.Cardinality == pref.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional + return (fd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Optional && fd.L1.ContainingOneof == nil) || fd.L1.IsProto3Optional } func (fd *Field) IsPacked() bool { - if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != pref.Proto2 && fd.L1.Cardinality == pref.Repeated { + if !fd.L1.HasPacked && fd.L0.ParentFile.L1.Syntax != protoreflect.Proto2 && fd.L1.Cardinality == protoreflect.Repeated { switch fd.L1.Kind { - case pref.StringKind, pref.BytesKind, pref.MessageKind, pref.GroupKind: + case protoreflect.StringKind, protoreflect.BytesKind, protoreflect.MessageKind, protoreflect.GroupKind: default: return true } @@ -290,40 +290,40 @@ func (fd *Field) IsPacked() bool { } func (fd *Field) IsExtension() bool { return false } func (fd *Field) IsWeak() bool { return fd.L1.IsWeak } -func (fd *Field) IsList() bool { return fd.Cardinality() == pref.Repeated && !fd.IsMap() } +func (fd *Field) IsList() bool { return fd.Cardinality() == protoreflect.Repeated && !fd.IsMap() } func (fd *Field) IsMap() bool { return fd.Message() != nil && fd.Message().IsMapEntry() } -func (fd *Field) MapKey() pref.FieldDescriptor { +func (fd *Field) MapKey() protoreflect.FieldDescriptor { if !fd.IsMap() { return nil } return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number) } -func (fd *Field) MapValue() pref.FieldDescriptor { +func (fd *Field) MapValue() protoreflect.FieldDescriptor { if !fd.IsMap() { return nil } return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number) } -func (fd *Field) HasDefault() bool { return fd.L1.Default.has } -func (fd *Field) Default() pref.Value { return fd.L1.Default.get(fd) } -func (fd *Field) DefaultEnumValue() pref.EnumValueDescriptor { return fd.L1.Default.enum } -func (fd *Field) ContainingOneof() pref.OneofDescriptor { return fd.L1.ContainingOneof } -func (fd *Field) ContainingMessage() pref.MessageDescriptor { - return fd.L0.Parent.(pref.MessageDescriptor) +func (fd *Field) HasDefault() bool { return fd.L1.Default.has } +func (fd *Field) Default() protoreflect.Value { return fd.L1.Default.get(fd) } +func (fd *Field) DefaultEnumValue() protoreflect.EnumValueDescriptor { return fd.L1.Default.enum } +func (fd *Field) ContainingOneof() protoreflect.OneofDescriptor { return fd.L1.ContainingOneof } +func (fd *Field) ContainingMessage() protoreflect.MessageDescriptor { + return fd.L0.Parent.(protoreflect.MessageDescriptor) } -func (fd *Field) Enum() pref.EnumDescriptor { +func (fd *Field) Enum() protoreflect.EnumDescriptor { return fd.L1.Enum } -func (fd *Field) Message() pref.MessageDescriptor { +func (fd *Field) Message() protoreflect.MessageDescriptor { if fd.L1.IsWeak { if d, _ := protoregistry.GlobalFiles.FindDescriptorByName(fd.L1.Message.FullName()); d != nil { - return d.(pref.MessageDescriptor) + return d.(protoreflect.MessageDescriptor) } } return fd.L1.Message } -func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) } -func (fd *Field) ProtoType(pref.FieldDescriptor) {} +func (fd *Field) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, fd) } +func (fd *Field) ProtoType(protoreflect.FieldDescriptor) {} // EnforceUTF8 is a pseudo-internal API to determine whether to enforce UTF-8 // validation for the string field. This exists for Google-internal use only @@ -336,21 +336,21 @@ func (fd *Field) EnforceUTF8() bool { if fd.L1.HasEnforceUTF8 { return fd.L1.EnforceUTF8 } - return fd.L0.ParentFile.L1.Syntax == pref.Proto3 + return fd.L0.ParentFile.L1.Syntax == protoreflect.Proto3 } func (od *Oneof) IsSynthetic() bool { - return od.L0.ParentFile.L1.Syntax == pref.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword() + return od.L0.ParentFile.L1.Syntax == protoreflect.Proto3 && len(od.L1.Fields.List) == 1 && od.L1.Fields.List[0].HasOptionalKeyword() } -func (od *Oneof) Options() pref.ProtoMessage { +func (od *Oneof) Options() protoreflect.ProtoMessage { if f := od.L1.Options; f != nil { return f() } return descopts.Oneof } -func (od *Oneof) Fields() pref.FieldDescriptors { return &od.L1.Fields } -func (od *Oneof) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, od) } -func (od *Oneof) ProtoType(pref.OneofDescriptor) {} +func (od *Oneof) Fields() protoreflect.FieldDescriptors { return &od.L1.Fields } +func (od *Oneof) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, od) } +func (od *Oneof) ProtoType(protoreflect.OneofDescriptor) {} type ( Extension struct { @@ -359,55 +359,57 @@ type ( L2 *ExtensionL2 // protected by fileDesc.once } ExtensionL1 struct { - Number pref.FieldNumber - Extendee pref.MessageDescriptor - Cardinality pref.Cardinality - Kind pref.Kind + Number protoreflect.FieldNumber + Extendee protoreflect.MessageDescriptor + Cardinality protoreflect.Cardinality + Kind protoreflect.Kind } ExtensionL2 struct { - Options func() pref.ProtoMessage + Options func() protoreflect.ProtoMessage StringName stringName IsProto3Optional bool // promoted from google.protobuf.FieldDescriptorProto IsPacked bool // promoted from google.protobuf.FieldOptions Default defaultValue - Enum pref.EnumDescriptor - Message pref.MessageDescriptor + Enum protoreflect.EnumDescriptor + Message protoreflect.MessageDescriptor } ) -func (xd *Extension) Options() pref.ProtoMessage { +func (xd *Extension) Options() protoreflect.ProtoMessage { if f := xd.lazyInit().Options; f != nil { return f() } return descopts.Field } -func (xd *Extension) Number() pref.FieldNumber { return xd.L1.Number } -func (xd *Extension) Cardinality() pref.Cardinality { return xd.L1.Cardinality } -func (xd *Extension) Kind() pref.Kind { return xd.L1.Kind } -func (xd *Extension) HasJSONName() bool { return xd.lazyInit().StringName.hasJSON } -func (xd *Extension) JSONName() string { return xd.lazyInit().StringName.getJSON(xd) } -func (xd *Extension) TextName() string { return xd.lazyInit().StringName.getText(xd) } -func (xd *Extension) HasPresence() bool { return xd.L1.Cardinality != pref.Repeated } +func (xd *Extension) Number() protoreflect.FieldNumber { return xd.L1.Number } +func (xd *Extension) Cardinality() protoreflect.Cardinality { return xd.L1.Cardinality } +func (xd *Extension) Kind() protoreflect.Kind { return xd.L1.Kind } +func (xd *Extension) HasJSONName() bool { return xd.lazyInit().StringName.hasJSON } +func (xd *Extension) JSONName() string { return xd.lazyInit().StringName.getJSON(xd) } +func (xd *Extension) TextName() string { return xd.lazyInit().StringName.getText(xd) } +func (xd *Extension) HasPresence() bool { return xd.L1.Cardinality != protoreflect.Repeated } func (xd *Extension) HasOptionalKeyword() bool { - return (xd.L0.ParentFile.L1.Syntax == pref.Proto2 && xd.L1.Cardinality == pref.Optional) || xd.lazyInit().IsProto3Optional + return (xd.L0.ParentFile.L1.Syntax == protoreflect.Proto2 && xd.L1.Cardinality == protoreflect.Optional) || xd.lazyInit().IsProto3Optional } -func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked } -func (xd *Extension) IsExtension() bool { return true } -func (xd *Extension) IsWeak() bool { return false } -func (xd *Extension) IsList() bool { return xd.Cardinality() == pref.Repeated } -func (xd *Extension) IsMap() bool { return false } -func (xd *Extension) MapKey() pref.FieldDescriptor { return nil } -func (xd *Extension) MapValue() pref.FieldDescriptor { return nil } -func (xd *Extension) HasDefault() bool { return xd.lazyInit().Default.has } -func (xd *Extension) Default() pref.Value { return xd.lazyInit().Default.get(xd) } -func (xd *Extension) DefaultEnumValue() pref.EnumValueDescriptor { return xd.lazyInit().Default.enum } -func (xd *Extension) ContainingOneof() pref.OneofDescriptor { return nil } -func (xd *Extension) ContainingMessage() pref.MessageDescriptor { return xd.L1.Extendee } -func (xd *Extension) Enum() pref.EnumDescriptor { return xd.lazyInit().Enum } -func (xd *Extension) Message() pref.MessageDescriptor { return xd.lazyInit().Message } -func (xd *Extension) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, xd) } -func (xd *Extension) ProtoType(pref.FieldDescriptor) {} -func (xd *Extension) ProtoInternal(pragma.DoNotImplement) {} +func (xd *Extension) IsPacked() bool { return xd.lazyInit().IsPacked } +func (xd *Extension) IsExtension() bool { return true } +func (xd *Extension) IsWeak() bool { return false } +func (xd *Extension) IsList() bool { return xd.Cardinality() == protoreflect.Repeated } +func (xd *Extension) IsMap() bool { return false } +func (xd *Extension) MapKey() protoreflect.FieldDescriptor { return nil } +func (xd *Extension) MapValue() protoreflect.FieldDescriptor { return nil } +func (xd *Extension) HasDefault() bool { return xd.lazyInit().Default.has } +func (xd *Extension) Default() protoreflect.Value { return xd.lazyInit().Default.get(xd) } +func (xd *Extension) DefaultEnumValue() protoreflect.EnumValueDescriptor { + return xd.lazyInit().Default.enum +} +func (xd *Extension) ContainingOneof() protoreflect.OneofDescriptor { return nil } +func (xd *Extension) ContainingMessage() protoreflect.MessageDescriptor { return xd.L1.Extendee } +func (xd *Extension) Enum() protoreflect.EnumDescriptor { return xd.lazyInit().Enum } +func (xd *Extension) Message() protoreflect.MessageDescriptor { return xd.lazyInit().Message } +func (xd *Extension) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, xd) } +func (xd *Extension) ProtoType(protoreflect.FieldDescriptor) {} +func (xd *Extension) ProtoInternal(pragma.DoNotImplement) {} func (xd *Extension) lazyInit() *ExtensionL2 { xd.L0.ParentFile.lazyInit() // implicitly initializes L2 return xd.L2 @@ -421,7 +423,7 @@ type ( } ServiceL1 struct{} ServiceL2 struct { - Options func() pref.ProtoMessage + Options func() protoreflect.ProtoMessage Methods Methods } @@ -430,48 +432,48 @@ type ( L1 MethodL1 } MethodL1 struct { - Options func() pref.ProtoMessage - Input pref.MessageDescriptor - Output pref.MessageDescriptor + Options func() protoreflect.ProtoMessage + Input protoreflect.MessageDescriptor + Output protoreflect.MessageDescriptor IsStreamingClient bool IsStreamingServer bool } ) -func (sd *Service) Options() pref.ProtoMessage { +func (sd *Service) Options() protoreflect.ProtoMessage { if f := sd.lazyInit().Options; f != nil { return f() } return descopts.Service } -func (sd *Service) Methods() pref.MethodDescriptors { return &sd.lazyInit().Methods } -func (sd *Service) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, sd) } -func (sd *Service) ProtoType(pref.ServiceDescriptor) {} -func (sd *Service) ProtoInternal(pragma.DoNotImplement) {} +func (sd *Service) Methods() protoreflect.MethodDescriptors { return &sd.lazyInit().Methods } +func (sd *Service) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, sd) } +func (sd *Service) ProtoType(protoreflect.ServiceDescriptor) {} +func (sd *Service) ProtoInternal(pragma.DoNotImplement) {} func (sd *Service) lazyInit() *ServiceL2 { sd.L0.ParentFile.lazyInit() // implicitly initializes L2 return sd.L2 } -func (md *Method) Options() pref.ProtoMessage { +func (md *Method) Options() protoreflect.ProtoMessage { if f := md.L1.Options; f != nil { return f() } return descopts.Method } -func (md *Method) Input() pref.MessageDescriptor { return md.L1.Input } -func (md *Method) Output() pref.MessageDescriptor { return md.L1.Output } -func (md *Method) IsStreamingClient() bool { return md.L1.IsStreamingClient } -func (md *Method) IsStreamingServer() bool { return md.L1.IsStreamingServer } -func (md *Method) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) } -func (md *Method) ProtoType(pref.MethodDescriptor) {} -func (md *Method) ProtoInternal(pragma.DoNotImplement) {} +func (md *Method) Input() protoreflect.MessageDescriptor { return md.L1.Input } +func (md *Method) Output() protoreflect.MessageDescriptor { return md.L1.Output } +func (md *Method) IsStreamingClient() bool { return md.L1.IsStreamingClient } +func (md *Method) IsStreamingServer() bool { return md.L1.IsStreamingServer } +func (md *Method) Format(s fmt.State, r rune) { descfmt.FormatDesc(s, r, md) } +func (md *Method) ProtoType(protoreflect.MethodDescriptor) {} +func (md *Method) ProtoInternal(pragma.DoNotImplement) {} // Surrogate files are can be used to create standalone descriptors // where the syntax is only information derived from the parent file. var ( - SurrogateProto2 = &File{L1: FileL1{Syntax: pref.Proto2}, L2: &FileL2{}} - SurrogateProto3 = &File{L1: FileL1{Syntax: pref.Proto3}, L2: &FileL2{}} + SurrogateProto2 = &File{L1: FileL1{Syntax: protoreflect.Proto2}, L2: &FileL2{}} + SurrogateProto3 = &File{L1: FileL1{Syntax: protoreflect.Proto3}, L2: &FileL2{}} ) type ( @@ -479,24 +481,24 @@ type ( L0 BaseL0 } BaseL0 struct { - FullName pref.FullName // must be populated - ParentFile *File // must be populated - Parent pref.Descriptor + FullName protoreflect.FullName // must be populated + ParentFile *File // must be populated + Parent protoreflect.Descriptor Index int } ) -func (d *Base) Name() pref.Name { return d.L0.FullName.Name() } -func (d *Base) FullName() pref.FullName { return d.L0.FullName } -func (d *Base) ParentFile() pref.FileDescriptor { +func (d *Base) Name() protoreflect.Name { return d.L0.FullName.Name() } +func (d *Base) FullName() protoreflect.FullName { return d.L0.FullName } +func (d *Base) ParentFile() protoreflect.FileDescriptor { if d.L0.ParentFile == SurrogateProto2 || d.L0.ParentFile == SurrogateProto3 { return nil // surrogate files are not real parents } return d.L0.ParentFile } -func (d *Base) Parent() pref.Descriptor { return d.L0.Parent } +func (d *Base) Parent() protoreflect.Descriptor { return d.L0.Parent } func (d *Base) Index() int { return d.L0.Index } -func (d *Base) Syntax() pref.Syntax { return d.L0.ParentFile.Syntax() } +func (d *Base) Syntax() protoreflect.Syntax { return d.L0.ParentFile.Syntax() } func (d *Base) IsPlaceholder() bool { return false } func (d *Base) ProtoInternal(pragma.DoNotImplement) {} @@ -513,7 +515,7 @@ func (s *stringName) InitJSON(name string) { s.nameJSON = name } -func (s *stringName) lazyInit(fd pref.FieldDescriptor) *stringName { +func (s *stringName) lazyInit(fd protoreflect.FieldDescriptor) *stringName { s.once.Do(func() { if fd.IsExtension() { // For extensions, JSON and text are formatted the same way. @@ -533,7 +535,7 @@ func (s *stringName) lazyInit(fd pref.FieldDescriptor) *stringName { // Format the text name. s.nameText = string(fd.Name()) - if fd.Kind() == pref.GroupKind { + if fd.Kind() == protoreflect.GroupKind { s.nameText = string(fd.Message().Name()) } } @@ -541,10 +543,10 @@ func (s *stringName) lazyInit(fd pref.FieldDescriptor) *stringName { return s } -func (s *stringName) getJSON(fd pref.FieldDescriptor) string { return s.lazyInit(fd).nameJSON } -func (s *stringName) getText(fd pref.FieldDescriptor) string { return s.lazyInit(fd).nameText } +func (s *stringName) getJSON(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameJSON } +func (s *stringName) getText(fd protoreflect.FieldDescriptor) string { return s.lazyInit(fd).nameText } -func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue { +func DefaultValue(v protoreflect.Value, ev protoreflect.EnumValueDescriptor) defaultValue { dv := defaultValue{has: v.IsValid(), val: v, enum: ev} if b, ok := v.Interface().([]byte); ok { // Store a copy of the default bytes, so that we can detect @@ -554,9 +556,9 @@ func DefaultValue(v pref.Value, ev pref.EnumValueDescriptor) defaultValue { return dv } -func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) defaultValue { - var evs pref.EnumValueDescriptors - if k == pref.EnumKind { +func unmarshalDefault(b []byte, k protoreflect.Kind, pf *File, ed protoreflect.EnumDescriptor) defaultValue { + var evs protoreflect.EnumValueDescriptors + if k == protoreflect.EnumKind { // If the enum is declared within the same file, be careful not to // blindly call the Values method, lest we bind ourselves in a deadlock. if e, ok := ed.(*Enum); ok && e.L0.ParentFile == pf { @@ -567,9 +569,9 @@ func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) d // If we are unable to resolve the enum dependency, use a placeholder // enum value since we will not be able to parse the default value. - if ed.IsPlaceholder() && pref.Name(b).IsValid() { - v := pref.ValueOfEnum(0) - ev := PlaceholderEnumValue(ed.FullName().Parent().Append(pref.Name(b))) + if ed.IsPlaceholder() && protoreflect.Name(b).IsValid() { + v := protoreflect.ValueOfEnum(0) + ev := PlaceholderEnumValue(ed.FullName().Parent().Append(protoreflect.Name(b))) return DefaultValue(v, ev) } } @@ -583,41 +585,41 @@ func unmarshalDefault(b []byte, k pref.Kind, pf *File, ed pref.EnumDescriptor) d type defaultValue struct { has bool - val pref.Value - enum pref.EnumValueDescriptor + val protoreflect.Value + enum protoreflect.EnumValueDescriptor bytes []byte } -func (dv *defaultValue) get(fd pref.FieldDescriptor) pref.Value { +func (dv *defaultValue) get(fd protoreflect.FieldDescriptor) protoreflect.Value { // Return the zero value as the default if unpopulated. if !dv.has { - if fd.Cardinality() == pref.Repeated { - return pref.Value{} + if fd.Cardinality() == protoreflect.Repeated { + return protoreflect.Value{} } switch fd.Kind() { - case pref.BoolKind: - return pref.ValueOfBool(false) - case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: - return pref.ValueOfInt32(0) - case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: - return pref.ValueOfInt64(0) - case pref.Uint32Kind, pref.Fixed32Kind: - return pref.ValueOfUint32(0) - case pref.Uint64Kind, pref.Fixed64Kind: - return pref.ValueOfUint64(0) - case pref.FloatKind: - return pref.ValueOfFloat32(0) - case pref.DoubleKind: - return pref.ValueOfFloat64(0) - case pref.StringKind: - return pref.ValueOfString("") - case pref.BytesKind: - return pref.ValueOfBytes(nil) - case pref.EnumKind: + case protoreflect.BoolKind: + return protoreflect.ValueOfBool(false) + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + return protoreflect.ValueOfInt32(0) + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + return protoreflect.ValueOfInt64(0) + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + return protoreflect.ValueOfUint32(0) + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + return protoreflect.ValueOfUint64(0) + case protoreflect.FloatKind: + return protoreflect.ValueOfFloat32(0) + case protoreflect.DoubleKind: + return protoreflect.ValueOfFloat64(0) + case protoreflect.StringKind: + return protoreflect.ValueOfString("") + case protoreflect.BytesKind: + return protoreflect.ValueOfBytes(nil) + case protoreflect.EnumKind: if evs := fd.Enum().Values(); evs.Len() > 0 { - return pref.ValueOfEnum(evs.Get(0).Number()) + return protoreflect.ValueOfEnum(evs.Get(0).Number()) } - return pref.ValueOfEnum(0) + return protoreflect.ValueOfEnum(0) } } diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go index 66e1fee52..4a1584c9d 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) // fileRaw is a data struct used when initializing a file descriptor from @@ -95,7 +95,7 @@ func (fd *File) unmarshalSeed(b []byte) { sb := getBuilder() defer putBuilder(sb) - var prevField pref.FieldNumber + var prevField protoreflect.FieldNumber var numEnums, numMessages, numExtensions, numServices int var posEnums, posMessages, posExtensions, posServices int b0 := b @@ -110,16 +110,16 @@ func (fd *File) unmarshalSeed(b []byte) { case genid.FileDescriptorProto_Syntax_field_number: switch string(v) { case "proto2": - fd.L1.Syntax = pref.Proto2 + fd.L1.Syntax = protoreflect.Proto2 case "proto3": - fd.L1.Syntax = pref.Proto3 + fd.L1.Syntax = protoreflect.Proto3 default: panic("invalid syntax") } case genid.FileDescriptorProto_Name_field_number: fd.L1.Path = sb.MakeString(v) case genid.FileDescriptorProto_Package_field_number: - fd.L1.Package = pref.FullName(sb.MakeString(v)) + fd.L1.Package = protoreflect.FullName(sb.MakeString(v)) case genid.FileDescriptorProto_EnumType_field_number: if prevField != genid.FileDescriptorProto_EnumType_field_number { if numEnums > 0 { @@ -163,7 +163,7 @@ func (fd *File) unmarshalSeed(b []byte) { // If syntax is missing, it is assumed to be proto2. if fd.L1.Syntax == 0 { - fd.L1.Syntax = pref.Proto2 + fd.L1.Syntax = protoreflect.Proto2 } // Must allocate all declarations before parsing each descriptor type @@ -219,7 +219,7 @@ func (fd *File) unmarshalSeed(b []byte) { } } -func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { ed.L0.ParentFile = pf ed.L0.Parent = pd ed.L0.Index = i @@ -271,12 +271,12 @@ func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Desc } } -func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { md.L0.ParentFile = pf md.L0.Parent = pd md.L0.Index = i - var prevField pref.FieldNumber + var prevField protoreflect.FieldNumber var numEnums, numMessages, numExtensions int var posEnums, posMessages, posExtensions int b0 := b @@ -387,7 +387,7 @@ func (md *Message) unmarshalSeedOptions(b []byte) { } } -func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { xd.L0.ParentFile = pf xd.L0.Parent = pd xd.L0.Index = i @@ -401,11 +401,11 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref b = b[m:] switch num { case genid.FieldDescriptorProto_Number_field_number: - xd.L1.Number = pref.FieldNumber(v) + xd.L1.Number = protoreflect.FieldNumber(v) case genid.FieldDescriptorProto_Label_field_number: - xd.L1.Cardinality = pref.Cardinality(v) + xd.L1.Cardinality = protoreflect.Cardinality(v) case genid.FieldDescriptorProto_Type_field_number: - xd.L1.Kind = pref.Kind(v) + xd.L1.Kind = protoreflect.Kind(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) @@ -423,7 +423,7 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref } } -func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { sd.L0.ParentFile = pf sd.L0.Parent = pd sd.L0.Index = i @@ -459,13 +459,13 @@ func putBuilder(b *strs.Builder) { // makeFullName converts b to a protoreflect.FullName, // where b must start with a leading dot. -func makeFullName(sb *strs.Builder, b []byte) pref.FullName { +func makeFullName(sb *strs.Builder, b []byte) protoreflect.FullName { if len(b) == 0 || b[0] != '.' { panic("name reference must be fully qualified") } - return pref.FullName(sb.MakeString(b[1:])) + return protoreflect.FullName(sb.MakeString(b[1:])) } -func appendFullName(sb *strs.Builder, prefix pref.FullName, suffix []byte) pref.FullName { - return sb.AppendFullName(prefix, pref.Name(strs.UnsafeString(suffix))) +func appendFullName(sb *strs.Builder, prefix protoreflect.FullName, suffix []byte) protoreflect.FullName { + return sb.AppendFullName(prefix, protoreflect.Name(strs.UnsafeString(suffix))) } diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go index 198451e3e..736a19a75 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go @@ -13,7 +13,7 @@ import ( "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/proto" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) func (fd *File) lazyRawInit() { @@ -39,10 +39,10 @@ func (file *File) resolveMessages() { // Resolve message field dependency. switch fd.L1.Kind { - case pref.EnumKind: + case protoreflect.EnumKind: fd.L1.Enum = file.resolveEnumDependency(fd.L1.Enum, listFieldDeps, depIdx) depIdx++ - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: fd.L1.Message = file.resolveMessageDependency(fd.L1.Message, listFieldDeps, depIdx) depIdx++ } @@ -62,10 +62,10 @@ func (file *File) resolveExtensions() { // Resolve extension field dependency. switch xd.L1.Kind { - case pref.EnumKind: + case protoreflect.EnumKind: xd.L2.Enum = file.resolveEnumDependency(xd.L2.Enum, listExtDeps, depIdx) depIdx++ - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: xd.L2.Message = file.resolveMessageDependency(xd.L2.Message, listExtDeps, depIdx) depIdx++ } @@ -92,7 +92,7 @@ func (file *File) resolveServices() { } } -func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref.EnumDescriptor { +func (file *File) resolveEnumDependency(ed protoreflect.EnumDescriptor, i, j int32) protoreflect.EnumDescriptor { r := file.builder.FileRegistry if r, ok := r.(resolverByIndex); ok { if ed2 := r.FindEnumByIndex(i, j, file.allEnums, file.allMessages); ed2 != nil { @@ -105,12 +105,12 @@ func (file *File) resolveEnumDependency(ed pref.EnumDescriptor, i, j int32) pref } } if d, _ := r.FindDescriptorByName(ed.FullName()); d != nil { - return d.(pref.EnumDescriptor) + return d.(protoreflect.EnumDescriptor) } return ed } -func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32) pref.MessageDescriptor { +func (file *File) resolveMessageDependency(md protoreflect.MessageDescriptor, i, j int32) protoreflect.MessageDescriptor { r := file.builder.FileRegistry if r, ok := r.(resolverByIndex); ok { if md2 := r.FindMessageByIndex(i, j, file.allEnums, file.allMessages); md2 != nil { @@ -123,7 +123,7 @@ func (file *File) resolveMessageDependency(md pref.MessageDescriptor, i, j int32 } } if d, _ := r.FindDescriptorByName(md.FullName()); d != nil { - return d.(pref.MessageDescriptor) + return d.(protoreflect.MessageDescriptor) } return md } @@ -158,7 +158,7 @@ func (fd *File) unmarshalFull(b []byte) { if imp == nil { imp = PlaceholderFile(path) } - fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp}) + fd.L2.Imports = append(fd.L2.Imports, protoreflect.FileImport{FileDescriptor: imp}) case genid.FileDescriptorProto_EnumType_field_number: fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb) enumIdx++ @@ -199,7 +199,7 @@ func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) { case genid.EnumDescriptorProto_Value_field_number: rawValues = append(rawValues, v) case genid.EnumDescriptorProto_ReservedName_field_number: - ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(sb.MakeString(v))) + ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v))) case genid.EnumDescriptorProto_ReservedRange_field_number: ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v)) case genid.EnumDescriptorProto_Options_field_number: @@ -219,7 +219,7 @@ func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) { ed.L2.Options = ed.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Enum, rawOptions) } -func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) { +func unmarshalEnumReservedRange(b []byte) (r [2]protoreflect.EnumNumber) { for len(b) > 0 { num, typ, n := protowire.ConsumeTag(b) b = b[n:] @@ -229,9 +229,9 @@ func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) { b = b[m:] switch num { case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number: - r[0] = pref.EnumNumber(v) + r[0] = protoreflect.EnumNumber(v) case genid.EnumDescriptorProto_EnumReservedRange_End_field_number: - r[1] = pref.EnumNumber(v) + r[1] = protoreflect.EnumNumber(v) } default: m := protowire.ConsumeFieldValue(num, typ, b) @@ -241,7 +241,7 @@ func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) { return r } -func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { vd.L0.ParentFile = pf vd.L0.Parent = pd vd.L0.Index = i @@ -256,7 +256,7 @@ func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref b = b[m:] switch num { case genid.EnumValueDescriptorProto_Number_field_number: - vd.L1.Number = pref.EnumNumber(v) + vd.L1.Number = protoreflect.EnumNumber(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) @@ -294,7 +294,7 @@ func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) { case genid.DescriptorProto_OneofDecl_field_number: rawOneofs = append(rawOneofs, v) case genid.DescriptorProto_ReservedName_field_number: - md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(sb.MakeString(v))) + md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, protoreflect.Name(sb.MakeString(v))) case genid.DescriptorProto_ReservedRange_field_number: md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v)) case genid.DescriptorProto_ExtensionRange_field_number: @@ -326,7 +326,7 @@ func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) { for i, b := range rawFields { fd := &md.L2.Fields.List[i] fd.unmarshalFull(b, sb, md.L0.ParentFile, md, i) - if fd.L1.Cardinality == pref.Required { + if fd.L1.Cardinality == protoreflect.Required { md.L2.RequiredNumbers.List = append(md.L2.RequiredNumbers.List, fd.L1.Number) } } @@ -359,7 +359,7 @@ func (md *Message) unmarshalOptions(b []byte) { } } -func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) { +func unmarshalMessageReservedRange(b []byte) (r [2]protoreflect.FieldNumber) { for len(b) > 0 { num, typ, n := protowire.ConsumeTag(b) b = b[n:] @@ -369,9 +369,9 @@ func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) { b = b[m:] switch num { case genid.DescriptorProto_ReservedRange_Start_field_number: - r[0] = pref.FieldNumber(v) + r[0] = protoreflect.FieldNumber(v) case genid.DescriptorProto_ReservedRange_End_field_number: - r[1] = pref.FieldNumber(v) + r[1] = protoreflect.FieldNumber(v) } default: m := protowire.ConsumeFieldValue(num, typ, b) @@ -381,7 +381,7 @@ func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) { return r } -func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions []byte) { +func unmarshalMessageExtensionRange(b []byte) (r [2]protoreflect.FieldNumber, rawOptions []byte) { for len(b) > 0 { num, typ, n := protowire.ConsumeTag(b) b = b[n:] @@ -391,9 +391,9 @@ func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions b = b[m:] switch num { case genid.DescriptorProto_ExtensionRange_Start_field_number: - r[0] = pref.FieldNumber(v) + r[0] = protoreflect.FieldNumber(v) case genid.DescriptorProto_ExtensionRange_End_field_number: - r[1] = pref.FieldNumber(v) + r[1] = protoreflect.FieldNumber(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) @@ -410,7 +410,7 @@ func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions return r, rawOptions } -func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { fd.L0.ParentFile = pf fd.L0.Parent = pd fd.L0.Index = i @@ -426,11 +426,11 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des b = b[m:] switch num { case genid.FieldDescriptorProto_Number_field_number: - fd.L1.Number = pref.FieldNumber(v) + fd.L1.Number = protoreflect.FieldNumber(v) case genid.FieldDescriptorProto_Label_field_number: - fd.L1.Cardinality = pref.Cardinality(v) + fd.L1.Cardinality = protoreflect.Cardinality(v) case genid.FieldDescriptorProto_Type_field_number: - fd.L1.Kind = pref.Kind(v) + fd.L1.Kind = protoreflect.Kind(v) case genid.FieldDescriptorProto_OneofIndex_field_number: // In Message.unmarshalFull, we allocate slices for both // the field and oneof descriptors before unmarshaling either @@ -453,7 +453,7 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des case genid.FieldDescriptorProto_JsonName_field_number: fd.L1.StringName.InitJSON(sb.MakeString(v)) case genid.FieldDescriptorProto_DefaultValue_field_number: - fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages + fd.L1.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages case genid.FieldDescriptorProto_TypeName_field_number: rawTypeName = v case genid.FieldDescriptorProto_Options_field_number: @@ -468,9 +468,9 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des if rawTypeName != nil { name := makeFullName(sb, rawTypeName) switch fd.L1.Kind { - case pref.EnumKind: + case protoreflect.EnumKind: fd.L1.Enum = PlaceholderEnum(name) - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: fd.L1.Message = PlaceholderMessage(name) } } @@ -504,7 +504,7 @@ func (fd *Field) unmarshalOptions(b []byte) { } } -func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { od.L0.ParentFile = pf od.L0.Parent = pd od.L0.Index = i @@ -553,7 +553,7 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { case genid.FieldDescriptorProto_JsonName_field_number: xd.L2.StringName.InitJSON(sb.MakeString(v)) case genid.FieldDescriptorProto_DefaultValue_field_number: - xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions + xd.L2.Default.val = protoreflect.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions case genid.FieldDescriptorProto_TypeName_field_number: rawTypeName = v case genid.FieldDescriptorProto_Options_field_number: @@ -568,9 +568,9 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { if rawTypeName != nil { name := makeFullName(sb, rawTypeName) switch xd.L1.Kind { - case pref.EnumKind: + case protoreflect.EnumKind: xd.L2.Enum = PlaceholderEnum(name) - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: xd.L2.Message = PlaceholderMessage(name) } } @@ -627,7 +627,7 @@ func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) { sd.L2.Options = sd.L0.ParentFile.builder.optionsUnmarshaler(&descopts.Service, rawOptions) } -func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Descriptor, i int) { +func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd protoreflect.Descriptor, i int) { md.L0.ParentFile = pf md.L0.Parent = pd md.L0.Index = i @@ -680,18 +680,18 @@ func appendOptions(dst, src []byte) []byte { // // The type of message to unmarshal to is passed as a pointer since the // vars in descopts may not yet be populated at the time this function is called. -func (db *Builder) optionsUnmarshaler(p *pref.ProtoMessage, b []byte) func() pref.ProtoMessage { +func (db *Builder) optionsUnmarshaler(p *protoreflect.ProtoMessage, b []byte) func() protoreflect.ProtoMessage { if b == nil { return nil } - var opts pref.ProtoMessage + var opts protoreflect.ProtoMessage var once sync.Once - return func() pref.ProtoMessage { + return func() protoreflect.ProtoMessage { once.Do(func() { if *p == nil { panic("Descriptor.Options called without importing the descriptor package") } - opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(pref.ProtoMessage) + opts = reflect.New(reflect.TypeOf(*p).Elem()).Interface().(protoreflect.ProtoMessage) if err := (proto.UnmarshalOptions{ AllowPartial: true, Resolver: db.TypeResolver, diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go index aa294fff9..e3b6587da 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go @@ -17,31 +17,30 @@ import ( "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/reflect/protoreflect" - pref "google.golang.org/protobuf/reflect/protoreflect" ) -type FileImports []pref.FileImport +type FileImports []protoreflect.FileImport func (p *FileImports) Len() int { return len(*p) } -func (p *FileImports) Get(i int) pref.FileImport { return (*p)[i] } +func (p *FileImports) Get(i int) protoreflect.FileImport { return (*p)[i] } func (p *FileImports) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) } func (p *FileImports) ProtoInternal(pragma.DoNotImplement) {} type Names struct { - List []pref.Name + List []protoreflect.Name once sync.Once - has map[pref.Name]int // protected by once + has map[protoreflect.Name]int // protected by once } func (p *Names) Len() int { return len(p.List) } -func (p *Names) Get(i int) pref.Name { return p.List[i] } -func (p *Names) Has(s pref.Name) bool { return p.lazyInit().has[s] > 0 } +func (p *Names) Get(i int) protoreflect.Name { return p.List[i] } +func (p *Names) Has(s protoreflect.Name) bool { return p.lazyInit().has[s] > 0 } func (p *Names) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) } func (p *Names) ProtoInternal(pragma.DoNotImplement) {} func (p *Names) lazyInit() *Names { p.once.Do(func() { if len(p.List) > 0 { - p.has = make(map[pref.Name]int, len(p.List)) + p.has = make(map[protoreflect.Name]int, len(p.List)) for _, s := range p.List { p.has[s] = p.has[s] + 1 } @@ -67,14 +66,14 @@ func (p *Names) CheckValid() error { } type EnumRanges struct { - List [][2]pref.EnumNumber // start inclusive; end inclusive + List [][2]protoreflect.EnumNumber // start inclusive; end inclusive once sync.Once - sorted [][2]pref.EnumNumber // protected by once + sorted [][2]protoreflect.EnumNumber // protected by once } -func (p *EnumRanges) Len() int { return len(p.List) } -func (p *EnumRanges) Get(i int) [2]pref.EnumNumber { return p.List[i] } -func (p *EnumRanges) Has(n pref.EnumNumber) bool { +func (p *EnumRanges) Len() int { return len(p.List) } +func (p *EnumRanges) Get(i int) [2]protoreflect.EnumNumber { return p.List[i] } +func (p *EnumRanges) Has(n protoreflect.EnumNumber) bool { for ls := p.lazyInit().sorted; len(ls) > 0; { i := len(ls) / 2 switch r := enumRange(ls[i]); { @@ -129,14 +128,14 @@ func (r enumRange) String() string { } type FieldRanges struct { - List [][2]pref.FieldNumber // start inclusive; end exclusive + List [][2]protoreflect.FieldNumber // start inclusive; end exclusive once sync.Once - sorted [][2]pref.FieldNumber // protected by once + sorted [][2]protoreflect.FieldNumber // protected by once } -func (p *FieldRanges) Len() int { return len(p.List) } -func (p *FieldRanges) Get(i int) [2]pref.FieldNumber { return p.List[i] } -func (p *FieldRanges) Has(n pref.FieldNumber) bool { +func (p *FieldRanges) Len() int { return len(p.List) } +func (p *FieldRanges) Get(i int) [2]protoreflect.FieldNumber { return p.List[i] } +func (p *FieldRanges) Has(n protoreflect.FieldNumber) bool { for ls := p.lazyInit().sorted; len(ls) > 0; { i := len(ls) / 2 switch r := fieldRange(ls[i]); { @@ -221,17 +220,17 @@ func (r fieldRange) String() string { } type FieldNumbers struct { - List []pref.FieldNumber + List []protoreflect.FieldNumber once sync.Once - has map[pref.FieldNumber]struct{} // protected by once + has map[protoreflect.FieldNumber]struct{} // protected by once } -func (p *FieldNumbers) Len() int { return len(p.List) } -func (p *FieldNumbers) Get(i int) pref.FieldNumber { return p.List[i] } -func (p *FieldNumbers) Has(n pref.FieldNumber) bool { +func (p *FieldNumbers) Len() int { return len(p.List) } +func (p *FieldNumbers) Get(i int) protoreflect.FieldNumber { return p.List[i] } +func (p *FieldNumbers) Has(n protoreflect.FieldNumber) bool { p.once.Do(func() { if len(p.List) > 0 { - p.has = make(map[pref.FieldNumber]struct{}, len(p.List)) + p.has = make(map[protoreflect.FieldNumber]struct{}, len(p.List)) for _, n := range p.List { p.has[n] = struct{}{} } @@ -244,30 +243,38 @@ func (p *FieldNumbers) Format(s fmt.State, r rune) { descfmt.FormatList func (p *FieldNumbers) ProtoInternal(pragma.DoNotImplement) {} type OneofFields struct { - List []pref.FieldDescriptor + List []protoreflect.FieldDescriptor once sync.Once - byName map[pref.Name]pref.FieldDescriptor // protected by once - byJSON map[string]pref.FieldDescriptor // protected by once - byText map[string]pref.FieldDescriptor // protected by once - byNum map[pref.FieldNumber]pref.FieldDescriptor // protected by once + byName map[protoreflect.Name]protoreflect.FieldDescriptor // protected by once + byJSON map[string]protoreflect.FieldDescriptor // protected by once + byText map[string]protoreflect.FieldDescriptor // protected by once + byNum map[protoreflect.FieldNumber]protoreflect.FieldDescriptor // protected by once } -func (p *OneofFields) Len() int { return len(p.List) } -func (p *OneofFields) Get(i int) pref.FieldDescriptor { return p.List[i] } -func (p *OneofFields) ByName(s pref.Name) pref.FieldDescriptor { return p.lazyInit().byName[s] } -func (p *OneofFields) ByJSONName(s string) pref.FieldDescriptor { return p.lazyInit().byJSON[s] } -func (p *OneofFields) ByTextName(s string) pref.FieldDescriptor { return p.lazyInit().byText[s] } -func (p *OneofFields) ByNumber(n pref.FieldNumber) pref.FieldDescriptor { return p.lazyInit().byNum[n] } -func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) } -func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {} +func (p *OneofFields) Len() int { return len(p.List) } +func (p *OneofFields) Get(i int) protoreflect.FieldDescriptor { return p.List[i] } +func (p *OneofFields) ByName(s protoreflect.Name) protoreflect.FieldDescriptor { + return p.lazyInit().byName[s] +} +func (p *OneofFields) ByJSONName(s string) protoreflect.FieldDescriptor { + return p.lazyInit().byJSON[s] +} +func (p *OneofFields) ByTextName(s string) protoreflect.FieldDescriptor { + return p.lazyInit().byText[s] +} +func (p *OneofFields) ByNumber(n protoreflect.FieldNumber) protoreflect.FieldDescriptor { + return p.lazyInit().byNum[n] +} +func (p *OneofFields) Format(s fmt.State, r rune) { descfmt.FormatList(s, r, p) } +func (p *OneofFields) ProtoInternal(pragma.DoNotImplement) {} func (p *OneofFields) lazyInit() *OneofFields { p.once.Do(func() { if len(p.List) > 0 { - p.byName = make(map[pref.Name]pref.FieldDescriptor, len(p.List)) - p.byJSON = make(map[string]pref.FieldDescriptor, len(p.List)) - p.byText = make(map[string]pref.FieldDescriptor, len(p.List)) - p.byNum = make(map[pref.FieldNumber]pref.FieldDescriptor, len(p.List)) + p.byName = make(map[protoreflect.Name]protoreflect.FieldDescriptor, len(p.List)) + p.byJSON = make(map[string]protoreflect.FieldDescriptor, len(p.List)) + p.byText = make(map[string]protoreflect.FieldDescriptor, len(p.List)) + p.byNum = make(map[protoreflect.FieldNumber]protoreflect.FieldDescriptor, len(p.List)) for _, f := range p.List { // Field names and numbers are guaranteed to be unique. p.byName[f.Name()] = f @@ -284,123 +291,123 @@ type SourceLocations struct { // List is a list of SourceLocations. // The SourceLocation.Next field does not need to be populated // as it will be lazily populated upon first need. - List []pref.SourceLocation + List []protoreflect.SourceLocation // File is the parent file descriptor that these locations are relative to. // If non-nil, ByDescriptor verifies that the provided descriptor // is a child of this file descriptor. - File pref.FileDescriptor + File protoreflect.FileDescriptor once sync.Once byPath map[pathKey]int } -func (p *SourceLocations) Len() int { return len(p.List) } -func (p *SourceLocations) Get(i int) pref.SourceLocation { return p.lazyInit().List[i] } -func (p *SourceLocations) byKey(k pathKey) pref.SourceLocation { +func (p *SourceLocations) Len() int { return len(p.List) } +func (p *SourceLocations) Get(i int) protoreflect.SourceLocation { return p.lazyInit().List[i] } +func (p *SourceLocations) byKey(k pathKey) protoreflect.SourceLocation { if i, ok := p.lazyInit().byPath[k]; ok { return p.List[i] } - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } -func (p *SourceLocations) ByPath(path pref.SourcePath) pref.SourceLocation { +func (p *SourceLocations) ByPath(path protoreflect.SourcePath) protoreflect.SourceLocation { return p.byKey(newPathKey(path)) } -func (p *SourceLocations) ByDescriptor(desc pref.Descriptor) pref.SourceLocation { +func (p *SourceLocations) ByDescriptor(desc protoreflect.Descriptor) protoreflect.SourceLocation { if p.File != nil && desc != nil && p.File != desc.ParentFile() { - return pref.SourceLocation{} // mismatching parent files + return protoreflect.SourceLocation{} // mismatching parent files } var pathArr [16]int32 path := pathArr[:0] for { switch desc.(type) { - case pref.FileDescriptor: + case protoreflect.FileDescriptor: // Reverse the path since it was constructed in reverse. for i, j := 0, len(path)-1; i < j; i, j = i+1, j-1 { path[i], path[j] = path[j], path[i] } return p.byKey(newPathKey(path)) - case pref.MessageDescriptor: + case protoreflect.MessageDescriptor: path = append(path, int32(desc.Index())) desc = desc.Parent() switch desc.(type) { - case pref.FileDescriptor: + case protoreflect.FileDescriptor: path = append(path, int32(genid.FileDescriptorProto_MessageType_field_number)) - case pref.MessageDescriptor: + case protoreflect.MessageDescriptor: path = append(path, int32(genid.DescriptorProto_NestedType_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } - case pref.FieldDescriptor: - isExtension := desc.(pref.FieldDescriptor).IsExtension() + case protoreflect.FieldDescriptor: + isExtension := desc.(protoreflect.FieldDescriptor).IsExtension() path = append(path, int32(desc.Index())) desc = desc.Parent() if isExtension { switch desc.(type) { - case pref.FileDescriptor: + case protoreflect.FileDescriptor: path = append(path, int32(genid.FileDescriptorProto_Extension_field_number)) - case pref.MessageDescriptor: + case protoreflect.MessageDescriptor: path = append(path, int32(genid.DescriptorProto_Extension_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } } else { switch desc.(type) { - case pref.MessageDescriptor: + case protoreflect.MessageDescriptor: path = append(path, int32(genid.DescriptorProto_Field_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } } - case pref.OneofDescriptor: + case protoreflect.OneofDescriptor: path = append(path, int32(desc.Index())) desc = desc.Parent() switch desc.(type) { - case pref.MessageDescriptor: + case protoreflect.MessageDescriptor: path = append(path, int32(genid.DescriptorProto_OneofDecl_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } - case pref.EnumDescriptor: + case protoreflect.EnumDescriptor: path = append(path, int32(desc.Index())) desc = desc.Parent() switch desc.(type) { - case pref.FileDescriptor: + case protoreflect.FileDescriptor: path = append(path, int32(genid.FileDescriptorProto_EnumType_field_number)) - case pref.MessageDescriptor: + case protoreflect.MessageDescriptor: path = append(path, int32(genid.DescriptorProto_EnumType_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } - case pref.EnumValueDescriptor: + case protoreflect.EnumValueDescriptor: path = append(path, int32(desc.Index())) desc = desc.Parent() switch desc.(type) { - case pref.EnumDescriptor: + case protoreflect.EnumDescriptor: path = append(path, int32(genid.EnumDescriptorProto_Value_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } - case pref.ServiceDescriptor: + case protoreflect.ServiceDescriptor: path = append(path, int32(desc.Index())) desc = desc.Parent() switch desc.(type) { - case pref.FileDescriptor: + case protoreflect.FileDescriptor: path = append(path, int32(genid.FileDescriptorProto_Service_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } - case pref.MethodDescriptor: + case protoreflect.MethodDescriptor: path = append(path, int32(desc.Index())) desc = desc.Parent() switch desc.(type) { - case pref.ServiceDescriptor: + case protoreflect.ServiceDescriptor: path = append(path, int32(genid.ServiceDescriptorProto_Method_field_number)) default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } default: - return pref.SourceLocation{} + return protoreflect.SourceLocation{} } } } @@ -435,7 +442,7 @@ type pathKey struct { str string // used if the path does not fit in arr } -func newPathKey(p pref.SourcePath) (k pathKey) { +func newPathKey(p protoreflect.SourcePath) (k pathKey) { if len(p) < len(k.arr) { for i, ps := range p { if ps < 0 || math.MaxUint8 <= ps { diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go b/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go index dbf2c605b..28240ebc5 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go @@ -7,7 +7,7 @@ package filedesc import ( "google.golang.org/protobuf/internal/descopts" "google.golang.org/protobuf/internal/pragma" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) var ( @@ -30,78 +30,80 @@ var ( // PlaceholderFile is a placeholder, representing only the file path. type PlaceholderFile string -func (f PlaceholderFile) ParentFile() pref.FileDescriptor { return f } -func (f PlaceholderFile) Parent() pref.Descriptor { return nil } -func (f PlaceholderFile) Index() int { return 0 } -func (f PlaceholderFile) Syntax() pref.Syntax { return 0 } -func (f PlaceholderFile) Name() pref.Name { return "" } -func (f PlaceholderFile) FullName() pref.FullName { return "" } -func (f PlaceholderFile) IsPlaceholder() bool { return true } -func (f PlaceholderFile) Options() pref.ProtoMessage { return descopts.File } -func (f PlaceholderFile) Path() string { return string(f) } -func (f PlaceholderFile) Package() pref.FullName { return "" } -func (f PlaceholderFile) Imports() pref.FileImports { return emptyFiles } -func (f PlaceholderFile) Messages() pref.MessageDescriptors { return emptyMessages } -func (f PlaceholderFile) Enums() pref.EnumDescriptors { return emptyEnums } -func (f PlaceholderFile) Extensions() pref.ExtensionDescriptors { return emptyExtensions } -func (f PlaceholderFile) Services() pref.ServiceDescriptors { return emptyServices } -func (f PlaceholderFile) SourceLocations() pref.SourceLocations { return emptySourceLocations } -func (f PlaceholderFile) ProtoType(pref.FileDescriptor) { return } -func (f PlaceholderFile) ProtoInternal(pragma.DoNotImplement) { return } +func (f PlaceholderFile) ParentFile() protoreflect.FileDescriptor { return f } +func (f PlaceholderFile) Parent() protoreflect.Descriptor { return nil } +func (f PlaceholderFile) Index() int { return 0 } +func (f PlaceholderFile) Syntax() protoreflect.Syntax { return 0 } +func (f PlaceholderFile) Name() protoreflect.Name { return "" } +func (f PlaceholderFile) FullName() protoreflect.FullName { return "" } +func (f PlaceholderFile) IsPlaceholder() bool { return true } +func (f PlaceholderFile) Options() protoreflect.ProtoMessage { return descopts.File } +func (f PlaceholderFile) Path() string { return string(f) } +func (f PlaceholderFile) Package() protoreflect.FullName { return "" } +func (f PlaceholderFile) Imports() protoreflect.FileImports { return emptyFiles } +func (f PlaceholderFile) Messages() protoreflect.MessageDescriptors { return emptyMessages } +func (f PlaceholderFile) Enums() protoreflect.EnumDescriptors { return emptyEnums } +func (f PlaceholderFile) Extensions() protoreflect.ExtensionDescriptors { return emptyExtensions } +func (f PlaceholderFile) Services() protoreflect.ServiceDescriptors { return emptyServices } +func (f PlaceholderFile) SourceLocations() protoreflect.SourceLocations { return emptySourceLocations } +func (f PlaceholderFile) ProtoType(protoreflect.FileDescriptor) { return } +func (f PlaceholderFile) ProtoInternal(pragma.DoNotImplement) { return } // PlaceholderEnum is a placeholder, representing only the full name. -type PlaceholderEnum pref.FullName +type PlaceholderEnum protoreflect.FullName -func (e PlaceholderEnum) ParentFile() pref.FileDescriptor { return nil } -func (e PlaceholderEnum) Parent() pref.Descriptor { return nil } -func (e PlaceholderEnum) Index() int { return 0 } -func (e PlaceholderEnum) Syntax() pref.Syntax { return 0 } -func (e PlaceholderEnum) Name() pref.Name { return pref.FullName(e).Name() } -func (e PlaceholderEnum) FullName() pref.FullName { return pref.FullName(e) } -func (e PlaceholderEnum) IsPlaceholder() bool { return true } -func (e PlaceholderEnum) Options() pref.ProtoMessage { return descopts.Enum } -func (e PlaceholderEnum) Values() pref.EnumValueDescriptors { return emptyEnumValues } -func (e PlaceholderEnum) ReservedNames() pref.Names { return emptyNames } -func (e PlaceholderEnum) ReservedRanges() pref.EnumRanges { return emptyEnumRanges } -func (e PlaceholderEnum) ProtoType(pref.EnumDescriptor) { return } -func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return } +func (e PlaceholderEnum) ParentFile() protoreflect.FileDescriptor { return nil } +func (e PlaceholderEnum) Parent() protoreflect.Descriptor { return nil } +func (e PlaceholderEnum) Index() int { return 0 } +func (e PlaceholderEnum) Syntax() protoreflect.Syntax { return 0 } +func (e PlaceholderEnum) Name() protoreflect.Name { return protoreflect.FullName(e).Name() } +func (e PlaceholderEnum) FullName() protoreflect.FullName { return protoreflect.FullName(e) } +func (e PlaceholderEnum) IsPlaceholder() bool { return true } +func (e PlaceholderEnum) Options() protoreflect.ProtoMessage { return descopts.Enum } +func (e PlaceholderEnum) Values() protoreflect.EnumValueDescriptors { return emptyEnumValues } +func (e PlaceholderEnum) ReservedNames() protoreflect.Names { return emptyNames } +func (e PlaceholderEnum) ReservedRanges() protoreflect.EnumRanges { return emptyEnumRanges } +func (e PlaceholderEnum) ProtoType(protoreflect.EnumDescriptor) { return } +func (e PlaceholderEnum) ProtoInternal(pragma.DoNotImplement) { return } // PlaceholderEnumValue is a placeholder, representing only the full name. -type PlaceholderEnumValue pref.FullName +type PlaceholderEnumValue protoreflect.FullName -func (e PlaceholderEnumValue) ParentFile() pref.FileDescriptor { return nil } -func (e PlaceholderEnumValue) Parent() pref.Descriptor { return nil } -func (e PlaceholderEnumValue) Index() int { return 0 } -func (e PlaceholderEnumValue) Syntax() pref.Syntax { return 0 } -func (e PlaceholderEnumValue) Name() pref.Name { return pref.FullName(e).Name() } -func (e PlaceholderEnumValue) FullName() pref.FullName { return pref.FullName(e) } -func (e PlaceholderEnumValue) IsPlaceholder() bool { return true } -func (e PlaceholderEnumValue) Options() pref.ProtoMessage { return descopts.EnumValue } -func (e PlaceholderEnumValue) Number() pref.EnumNumber { return 0 } -func (e PlaceholderEnumValue) ProtoType(pref.EnumValueDescriptor) { return } -func (e PlaceholderEnumValue) ProtoInternal(pragma.DoNotImplement) { return } +func (e PlaceholderEnumValue) ParentFile() protoreflect.FileDescriptor { return nil } +func (e PlaceholderEnumValue) Parent() protoreflect.Descriptor { return nil } +func (e PlaceholderEnumValue) Index() int { return 0 } +func (e PlaceholderEnumValue) Syntax() protoreflect.Syntax { return 0 } +func (e PlaceholderEnumValue) Name() protoreflect.Name { return protoreflect.FullName(e).Name() } +func (e PlaceholderEnumValue) FullName() protoreflect.FullName { return protoreflect.FullName(e) } +func (e PlaceholderEnumValue) IsPlaceholder() bool { return true } +func (e PlaceholderEnumValue) Options() protoreflect.ProtoMessage { return descopts.EnumValue } +func (e PlaceholderEnumValue) Number() protoreflect.EnumNumber { return 0 } +func (e PlaceholderEnumValue) ProtoType(protoreflect.EnumValueDescriptor) { return } +func (e PlaceholderEnumValue) ProtoInternal(pragma.DoNotImplement) { return } // PlaceholderMessage is a placeholder, representing only the full name. -type PlaceholderMessage pref.FullName +type PlaceholderMessage protoreflect.FullName -func (m PlaceholderMessage) ParentFile() pref.FileDescriptor { return nil } -func (m PlaceholderMessage) Parent() pref.Descriptor { return nil } -func (m PlaceholderMessage) Index() int { return 0 } -func (m PlaceholderMessage) Syntax() pref.Syntax { return 0 } -func (m PlaceholderMessage) Name() pref.Name { return pref.FullName(m).Name() } -func (m PlaceholderMessage) FullName() pref.FullName { return pref.FullName(m) } -func (m PlaceholderMessage) IsPlaceholder() bool { return true } -func (m PlaceholderMessage) Options() pref.ProtoMessage { return descopts.Message } -func (m PlaceholderMessage) IsMapEntry() bool { return false } -func (m PlaceholderMessage) Fields() pref.FieldDescriptors { return emptyFields } -func (m PlaceholderMessage) Oneofs() pref.OneofDescriptors { return emptyOneofs } -func (m PlaceholderMessage) ReservedNames() pref.Names { return emptyNames } -func (m PlaceholderMessage) ReservedRanges() pref.FieldRanges { return emptyFieldRanges } -func (m PlaceholderMessage) RequiredNumbers() pref.FieldNumbers { return emptyFieldNumbers } -func (m PlaceholderMessage) ExtensionRanges() pref.FieldRanges { return emptyFieldRanges } -func (m PlaceholderMessage) ExtensionRangeOptions(int) pref.ProtoMessage { panic("index out of range") } -func (m PlaceholderMessage) Messages() pref.MessageDescriptors { return emptyMessages } -func (m PlaceholderMessage) Enums() pref.EnumDescriptors { return emptyEnums } -func (m PlaceholderMessage) Extensions() pref.ExtensionDescriptors { return emptyExtensions } -func (m PlaceholderMessage) ProtoType(pref.MessageDescriptor) { return } -func (m PlaceholderMessage) ProtoInternal(pragma.DoNotImplement) { return } +func (m PlaceholderMessage) ParentFile() protoreflect.FileDescriptor { return nil } +func (m PlaceholderMessage) Parent() protoreflect.Descriptor { return nil } +func (m PlaceholderMessage) Index() int { return 0 } +func (m PlaceholderMessage) Syntax() protoreflect.Syntax { return 0 } +func (m PlaceholderMessage) Name() protoreflect.Name { return protoreflect.FullName(m).Name() } +func (m PlaceholderMessage) FullName() protoreflect.FullName { return protoreflect.FullName(m) } +func (m PlaceholderMessage) IsPlaceholder() bool { return true } +func (m PlaceholderMessage) Options() protoreflect.ProtoMessage { return descopts.Message } +func (m PlaceholderMessage) IsMapEntry() bool { return false } +func (m PlaceholderMessage) Fields() protoreflect.FieldDescriptors { return emptyFields } +func (m PlaceholderMessage) Oneofs() protoreflect.OneofDescriptors { return emptyOneofs } +func (m PlaceholderMessage) ReservedNames() protoreflect.Names { return emptyNames } +func (m PlaceholderMessage) ReservedRanges() protoreflect.FieldRanges { return emptyFieldRanges } +func (m PlaceholderMessage) RequiredNumbers() protoreflect.FieldNumbers { return emptyFieldNumbers } +func (m PlaceholderMessage) ExtensionRanges() protoreflect.FieldRanges { return emptyFieldRanges } +func (m PlaceholderMessage) ExtensionRangeOptions(int) protoreflect.ProtoMessage { + panic("index out of range") +} +func (m PlaceholderMessage) Messages() protoreflect.MessageDescriptors { return emptyMessages } +func (m PlaceholderMessage) Enums() protoreflect.EnumDescriptors { return emptyEnums } +func (m PlaceholderMessage) Extensions() protoreflect.ExtensionDescriptors { return emptyExtensions } +func (m PlaceholderMessage) ProtoType(protoreflect.MessageDescriptor) { return } +func (m PlaceholderMessage) ProtoInternal(pragma.DoNotImplement) { return } diff --git a/vendor/google.golang.org/protobuf/internal/filetype/build.go b/vendor/google.golang.org/protobuf/internal/filetype/build.go index 0a0dd35de..f0e38c4ef 100644 --- a/vendor/google.golang.org/protobuf/internal/filetype/build.go +++ b/vendor/google.golang.org/protobuf/internal/filetype/build.go @@ -10,17 +10,16 @@ import ( "reflect" "google.golang.org/protobuf/internal/descopts" - fdesc "google.golang.org/protobuf/internal/filedesc" + "google.golang.org/protobuf/internal/filedesc" pimpl "google.golang.org/protobuf/internal/impl" - pref "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" ) // Builder constructs type descriptors from a raw file descriptor // and associated Go types for each enum and message declaration. // -// -// Flattened Ordering +// # Flattened Ordering // // The protobuf type system represents declarations as a tree. Certain nodes in // the tree require us to either associate it with a concrete Go type or to @@ -52,7 +51,7 @@ import ( // that children themselves may have. type Builder struct { // File is the underlying file descriptor builder. - File fdesc.Builder + File filedesc.Builder // GoTypes is a unique set of the Go types for all declarations and // dependencies. Each type is represented as a zero value of the Go type. @@ -108,22 +107,22 @@ type Builder struct { // TypeRegistry is the registry to register each type descriptor. // If nil, it uses protoregistry.GlobalTypes. TypeRegistry interface { - RegisterMessage(pref.MessageType) error - RegisterEnum(pref.EnumType) error - RegisterExtension(pref.ExtensionType) error + RegisterMessage(protoreflect.MessageType) error + RegisterEnum(protoreflect.EnumType) error + RegisterExtension(protoreflect.ExtensionType) error } } // Out is the output of the builder. type Out struct { - File pref.FileDescriptor + File protoreflect.FileDescriptor } func (tb Builder) Build() (out Out) { // Replace the resolver with one that resolves dependencies by index, // which is faster and more reliable than relying on the global registry. if tb.File.FileRegistry == nil { - tb.File.FileRegistry = preg.GlobalFiles + tb.File.FileRegistry = protoregistry.GlobalFiles } tb.File.FileRegistry = &resolverByIndex{ goTypes: tb.GoTypes, @@ -133,7 +132,7 @@ func (tb Builder) Build() (out Out) { // Initialize registry if unpopulated. if tb.TypeRegistry == nil { - tb.TypeRegistry = preg.GlobalTypes + tb.TypeRegistry = protoregistry.GlobalTypes } fbOut := tb.File.Build() @@ -183,23 +182,23 @@ func (tb Builder) Build() (out Out) { for i := range fbOut.Messages { switch fbOut.Messages[i].Name() { case "FileOptions": - descopts.File = messageGoTypes[i].(pref.ProtoMessage) + descopts.File = messageGoTypes[i].(protoreflect.ProtoMessage) case "EnumOptions": - descopts.Enum = messageGoTypes[i].(pref.ProtoMessage) + descopts.Enum = messageGoTypes[i].(protoreflect.ProtoMessage) case "EnumValueOptions": - descopts.EnumValue = messageGoTypes[i].(pref.ProtoMessage) + descopts.EnumValue = messageGoTypes[i].(protoreflect.ProtoMessage) case "MessageOptions": - descopts.Message = messageGoTypes[i].(pref.ProtoMessage) + descopts.Message = messageGoTypes[i].(protoreflect.ProtoMessage) case "FieldOptions": - descopts.Field = messageGoTypes[i].(pref.ProtoMessage) + descopts.Field = messageGoTypes[i].(protoreflect.ProtoMessage) case "OneofOptions": - descopts.Oneof = messageGoTypes[i].(pref.ProtoMessage) + descopts.Oneof = messageGoTypes[i].(protoreflect.ProtoMessage) case "ExtensionRangeOptions": - descopts.ExtensionRange = messageGoTypes[i].(pref.ProtoMessage) + descopts.ExtensionRange = messageGoTypes[i].(protoreflect.ProtoMessage) case "ServiceOptions": - descopts.Service = messageGoTypes[i].(pref.ProtoMessage) + descopts.Service = messageGoTypes[i].(protoreflect.ProtoMessage) case "MethodOptions": - descopts.Method = messageGoTypes[i].(pref.ProtoMessage) + descopts.Method = messageGoTypes[i].(protoreflect.ProtoMessage) } } } @@ -216,11 +215,11 @@ func (tb Builder) Build() (out Out) { const listExtDeps = 2 var goType reflect.Type switch fbOut.Extensions[i].L1.Kind { - case pref.EnumKind: + case protoreflect.EnumKind: j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx) goType = reflect.TypeOf(tb.GoTypes[j]) depIdx++ - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: j := depIdxs.Get(tb.DependencyIndexes, listExtDeps, depIdx) goType = reflect.TypeOf(tb.GoTypes[j]) depIdx++ @@ -242,22 +241,22 @@ func (tb Builder) Build() (out Out) { return out } -var goTypeForPBKind = map[pref.Kind]reflect.Type{ - pref.BoolKind: reflect.TypeOf(bool(false)), - pref.Int32Kind: reflect.TypeOf(int32(0)), - pref.Sint32Kind: reflect.TypeOf(int32(0)), - pref.Sfixed32Kind: reflect.TypeOf(int32(0)), - pref.Int64Kind: reflect.TypeOf(int64(0)), - pref.Sint64Kind: reflect.TypeOf(int64(0)), - pref.Sfixed64Kind: reflect.TypeOf(int64(0)), - pref.Uint32Kind: reflect.TypeOf(uint32(0)), - pref.Fixed32Kind: reflect.TypeOf(uint32(0)), - pref.Uint64Kind: reflect.TypeOf(uint64(0)), - pref.Fixed64Kind: reflect.TypeOf(uint64(0)), - pref.FloatKind: reflect.TypeOf(float32(0)), - pref.DoubleKind: reflect.TypeOf(float64(0)), - pref.StringKind: reflect.TypeOf(string("")), - pref.BytesKind: reflect.TypeOf([]byte(nil)), +var goTypeForPBKind = map[protoreflect.Kind]reflect.Type{ + protoreflect.BoolKind: reflect.TypeOf(bool(false)), + protoreflect.Int32Kind: reflect.TypeOf(int32(0)), + protoreflect.Sint32Kind: reflect.TypeOf(int32(0)), + protoreflect.Sfixed32Kind: reflect.TypeOf(int32(0)), + protoreflect.Int64Kind: reflect.TypeOf(int64(0)), + protoreflect.Sint64Kind: reflect.TypeOf(int64(0)), + protoreflect.Sfixed64Kind: reflect.TypeOf(int64(0)), + protoreflect.Uint32Kind: reflect.TypeOf(uint32(0)), + protoreflect.Fixed32Kind: reflect.TypeOf(uint32(0)), + protoreflect.Uint64Kind: reflect.TypeOf(uint64(0)), + protoreflect.Fixed64Kind: reflect.TypeOf(uint64(0)), + protoreflect.FloatKind: reflect.TypeOf(float32(0)), + protoreflect.DoubleKind: reflect.TypeOf(float64(0)), + protoreflect.StringKind: reflect.TypeOf(string("")), + protoreflect.BytesKind: reflect.TypeOf([]byte(nil)), } type depIdxs []int32 @@ -274,13 +273,13 @@ type ( fileRegistry } fileRegistry interface { - FindFileByPath(string) (pref.FileDescriptor, error) - FindDescriptorByName(pref.FullName) (pref.Descriptor, error) - RegisterFile(pref.FileDescriptor) error + FindFileByPath(string) (protoreflect.FileDescriptor, error) + FindDescriptorByName(protoreflect.FullName) (protoreflect.Descriptor, error) + RegisterFile(protoreflect.FileDescriptor) error } ) -func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.EnumDescriptor { +func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []filedesc.Enum, ms []filedesc.Message) protoreflect.EnumDescriptor { if depIdx := int(r.depIdxs.Get(i, j)); int(depIdx) < len(es)+len(ms) { return &es[depIdx] } else { @@ -288,7 +287,7 @@ func (r *resolverByIndex) FindEnumByIndex(i, j int32, es []fdesc.Enum, ms []fdes } } -func (r *resolverByIndex) FindMessageByIndex(i, j int32, es []fdesc.Enum, ms []fdesc.Message) pref.MessageDescriptor { +func (r *resolverByIndex) FindMessageByIndex(i, j int32, es []filedesc.Enum, ms []filedesc.Message) protoreflect.MessageDescriptor { if depIdx := int(r.depIdxs.Get(i, j)); depIdx < len(es)+len(ms) { return &ms[depIdx-len(es)] } else { diff --git a/vendor/google.golang.org/protobuf/internal/impl/api_export.go b/vendor/google.golang.org/protobuf/internal/impl/api_export.go index abee5f30e..a371f98de 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/api_export.go +++ b/vendor/google.golang.org/protobuf/internal/impl/api_export.go @@ -12,8 +12,8 @@ import ( "google.golang.org/protobuf/encoding/prototext" "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/proto" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" ) // Export is a zero-length named type that exists only to export a set of @@ -32,11 +32,11 @@ type enum = interface{} // EnumOf returns the protoreflect.Enum interface over e. // It returns nil if e is nil. -func (Export) EnumOf(e enum) pref.Enum { +func (Export) EnumOf(e enum) protoreflect.Enum { switch e := e.(type) { case nil: return nil - case pref.Enum: + case protoreflect.Enum: return e default: return legacyWrapEnum(reflect.ValueOf(e)) @@ -45,11 +45,11 @@ func (Export) EnumOf(e enum) pref.Enum { // EnumDescriptorOf returns the protoreflect.EnumDescriptor for e. // It returns nil if e is nil. -func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor { +func (Export) EnumDescriptorOf(e enum) protoreflect.EnumDescriptor { switch e := e.(type) { case nil: return nil - case pref.Enum: + case protoreflect.Enum: return e.Descriptor() default: return LegacyLoadEnumDesc(reflect.TypeOf(e)) @@ -58,11 +58,11 @@ func (Export) EnumDescriptorOf(e enum) pref.EnumDescriptor { // EnumTypeOf returns the protoreflect.EnumType for e. // It returns nil if e is nil. -func (Export) EnumTypeOf(e enum) pref.EnumType { +func (Export) EnumTypeOf(e enum) protoreflect.EnumType { switch e := e.(type) { case nil: return nil - case pref.Enum: + case protoreflect.Enum: return e.Type() default: return legacyLoadEnumType(reflect.TypeOf(e)) @@ -71,7 +71,7 @@ func (Export) EnumTypeOf(e enum) pref.EnumType { // EnumStringOf returns the enum value as a string, either as the name if // the number is resolvable, or the number formatted as a string. -func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string { +func (Export) EnumStringOf(ed protoreflect.EnumDescriptor, n protoreflect.EnumNumber) string { ev := ed.Values().ByNumber(n) if ev != nil { return string(ev.Name()) @@ -84,7 +84,7 @@ func (Export) EnumStringOf(ed pref.EnumDescriptor, n pref.EnumNumber) string { type message = interface{} // legacyMessageWrapper wraps a v2 message as a v1 message. -type legacyMessageWrapper struct{ m pref.ProtoMessage } +type legacyMessageWrapper struct{ m protoreflect.ProtoMessage } func (m legacyMessageWrapper) Reset() { proto.Reset(m.m) } func (m legacyMessageWrapper) String() string { return Export{}.MessageStringOf(m.m) } @@ -92,30 +92,30 @@ func (m legacyMessageWrapper) ProtoMessage() {} // ProtoMessageV1Of converts either a v1 or v2 message to a v1 message. // It returns nil if m is nil. -func (Export) ProtoMessageV1Of(m message) piface.MessageV1 { +func (Export) ProtoMessageV1Of(m message) protoiface.MessageV1 { switch mv := m.(type) { case nil: return nil - case piface.MessageV1: + case protoiface.MessageV1: return mv case unwrapper: return Export{}.ProtoMessageV1Of(mv.protoUnwrap()) - case pref.ProtoMessage: + case protoreflect.ProtoMessage: return legacyMessageWrapper{mv} default: panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m)) } } -func (Export) protoMessageV2Of(m message) pref.ProtoMessage { +func (Export) protoMessageV2Of(m message) protoreflect.ProtoMessage { switch mv := m.(type) { case nil: return nil - case pref.ProtoMessage: + case protoreflect.ProtoMessage: return mv case legacyMessageWrapper: return mv.m - case piface.MessageV1: + case protoiface.MessageV1: return nil default: panic(fmt.Sprintf("message %T is neither a v1 or v2 Message", m)) @@ -124,7 +124,7 @@ func (Export) protoMessageV2Of(m message) pref.ProtoMessage { // ProtoMessageV2Of converts either a v1 or v2 message to a v2 message. // It returns nil if m is nil. -func (Export) ProtoMessageV2Of(m message) pref.ProtoMessage { +func (Export) ProtoMessageV2Of(m message) protoreflect.ProtoMessage { if m == nil { return nil } @@ -136,7 +136,7 @@ func (Export) ProtoMessageV2Of(m message) pref.ProtoMessage { // MessageOf returns the protoreflect.Message interface over m. // It returns nil if m is nil. -func (Export) MessageOf(m message) pref.Message { +func (Export) MessageOf(m message) protoreflect.Message { if m == nil { return nil } @@ -148,7 +148,7 @@ func (Export) MessageOf(m message) pref.Message { // MessageDescriptorOf returns the protoreflect.MessageDescriptor for m. // It returns nil if m is nil. -func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor { +func (Export) MessageDescriptorOf(m message) protoreflect.MessageDescriptor { if m == nil { return nil } @@ -160,7 +160,7 @@ func (Export) MessageDescriptorOf(m message) pref.MessageDescriptor { // MessageTypeOf returns the protoreflect.MessageType for m. // It returns nil if m is nil. -func (Export) MessageTypeOf(m message) pref.MessageType { +func (Export) MessageTypeOf(m message) protoreflect.MessageType { if m == nil { return nil } @@ -172,6 +172,6 @@ func (Export) MessageTypeOf(m message) pref.MessageType { // MessageStringOf returns the message value as a string, // which is the message serialized in the protobuf text format. -func (Export) MessageStringOf(m pref.ProtoMessage) string { +func (Export) MessageStringOf(m protoreflect.ProtoMessage) string { return prototext.MarshalOptions{Multiline: false}.Format(m) } diff --git a/vendor/google.golang.org/protobuf/internal/impl/checkinit.go b/vendor/google.golang.org/protobuf/internal/impl/checkinit.go index b82341e57..bff041edc 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/checkinit.go +++ b/vendor/google.golang.org/protobuf/internal/impl/checkinit.go @@ -8,18 +8,18 @@ import ( "sync" "google.golang.org/protobuf/internal/errors" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" ) -func (mi *MessageInfo) checkInitialized(in piface.CheckInitializedInput) (piface.CheckInitializedOutput, error) { +func (mi *MessageInfo) checkInitialized(in protoiface.CheckInitializedInput) (protoiface.CheckInitializedOutput, error) { var p pointer if ms, ok := in.Message.(*messageState); ok { p = ms.pointer() } else { p = in.Message.(*messageReflectWrapper).pointer() } - return piface.CheckInitializedOutput{}, mi.checkInitializedPointer(p) + return protoiface.CheckInitializedOutput{}, mi.checkInitializedPointer(p) } func (mi *MessageInfo) checkInitializedPointer(p pointer) error { @@ -90,7 +90,7 @@ var ( // needsInitCheck reports whether a message needs to be checked for partial initialization. // // It returns true if the message transitively includes any required or extension fields. -func needsInitCheck(md pref.MessageDescriptor) bool { +func needsInitCheck(md protoreflect.MessageDescriptor) bool { if v, ok := needsInitCheckMap.Load(md); ok { if has, ok := v.(bool); ok { return has @@ -101,7 +101,7 @@ func needsInitCheck(md pref.MessageDescriptor) bool { return needsInitCheckLocked(md) } -func needsInitCheckLocked(md pref.MessageDescriptor) (has bool) { +func needsInitCheckLocked(md protoreflect.MessageDescriptor) (has bool) { if v, ok := needsInitCheckMap.Load(md); ok { // If has is true, we've previously determined that this message // needs init checks. diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go b/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go index 08d35170b..e74cefdc5 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_extension.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type extensionFieldInfo struct { @@ -23,7 +23,7 @@ type extensionFieldInfo struct { var legacyExtensionFieldInfoCache sync.Map // map[protoreflect.ExtensionType]*extensionFieldInfo -func getExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo { +func getExtensionFieldInfo(xt protoreflect.ExtensionType) *extensionFieldInfo { if xi, ok := xt.(*ExtensionInfo); ok { xi.lazyInit() return xi.info @@ -32,7 +32,7 @@ func getExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo { } // legacyLoadExtensionFieldInfo dynamically loads a *ExtensionInfo for xt. -func legacyLoadExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo { +func legacyLoadExtensionFieldInfo(xt protoreflect.ExtensionType) *extensionFieldInfo { if xi, ok := legacyExtensionFieldInfoCache.Load(xt); ok { return xi.(*extensionFieldInfo) } @@ -43,7 +43,7 @@ func legacyLoadExtensionFieldInfo(xt pref.ExtensionType) *extensionFieldInfo { return e } -func makeExtensionFieldInfo(xd pref.ExtensionDescriptor) *extensionFieldInfo { +func makeExtensionFieldInfo(xd protoreflect.ExtensionDescriptor) *extensionFieldInfo { var wiretag uint64 if !xd.IsPacked() { wiretag = protowire.EncodeTag(xd.Number(), wireTypes[xd.Kind()]) @@ -59,10 +59,10 @@ func makeExtensionFieldInfo(xd pref.ExtensionDescriptor) *extensionFieldInfo { // This is true for composite types, where we pass in a message, list, or map to fill in, // and for enums, where we pass in a prototype value to specify the concrete enum type. switch xd.Kind() { - case pref.MessageKind, pref.GroupKind, pref.EnumKind: + case protoreflect.MessageKind, protoreflect.GroupKind, protoreflect.EnumKind: e.unmarshalNeedsValue = true default: - if xd.Cardinality() == pref.Repeated { + if xd.Cardinality() == protoreflect.Repeated { e.unmarshalNeedsValue = true } } @@ -73,21 +73,21 @@ type lazyExtensionValue struct { atomicOnce uint32 // atomically set if value is valid mu sync.Mutex xi *extensionFieldInfo - value pref.Value + value protoreflect.Value b []byte - fn func() pref.Value + fn func() protoreflect.Value } type ExtensionField struct { - typ pref.ExtensionType + typ protoreflect.ExtensionType // value is either the value of GetValue, // or a *lazyExtensionValue that then returns the value of GetValue. - value pref.Value + value protoreflect.Value lazy *lazyExtensionValue } -func (f *ExtensionField) appendLazyBytes(xt pref.ExtensionType, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, b []byte) { +func (f *ExtensionField) appendLazyBytes(xt protoreflect.ExtensionType, xi *extensionFieldInfo, num protowire.Number, wtyp protowire.Type, b []byte) { if f.lazy == nil { f.lazy = &lazyExtensionValue{xi: xi} } @@ -97,7 +97,7 @@ func (f *ExtensionField) appendLazyBytes(xt pref.ExtensionType, xi *extensionFie f.lazy.b = append(f.lazy.b, b...) } -func (f *ExtensionField) canLazy(xt pref.ExtensionType) bool { +func (f *ExtensionField) canLazy(xt protoreflect.ExtensionType) bool { if f.typ == nil { return true } @@ -154,7 +154,7 @@ func (f *ExtensionField) lazyInit() { // Set sets the type and value of the extension field. // This must not be called concurrently. -func (f *ExtensionField) Set(t pref.ExtensionType, v pref.Value) { +func (f *ExtensionField) Set(t protoreflect.ExtensionType, v protoreflect.Value) { f.typ = t f.value = v f.lazy = nil @@ -162,14 +162,14 @@ func (f *ExtensionField) Set(t pref.ExtensionType, v pref.Value) { // SetLazy sets the type and a value that is to be lazily evaluated upon first use. // This must not be called concurrently. -func (f *ExtensionField) SetLazy(t pref.ExtensionType, fn func() pref.Value) { +func (f *ExtensionField) SetLazy(t protoreflect.ExtensionType, fn func() protoreflect.Value) { f.typ = t f.lazy = &lazyExtensionValue{fn: fn} } // Value returns the value of the extension field. // This may be called concurrently. -func (f *ExtensionField) Value() pref.Value { +func (f *ExtensionField) Value() protoreflect.Value { if f.lazy != nil { if atomic.LoadUint32(&f.lazy.atomicOnce) == 0 { f.lazyInit() @@ -181,7 +181,7 @@ func (f *ExtensionField) Value() pref.Value { // Type returns the type of the extension field. // This may be called concurrently. -func (f ExtensionField) Type() pref.ExtensionType { +func (f ExtensionField) Type() protoreflect.ExtensionType { return f.typ } @@ -193,7 +193,7 @@ func (f ExtensionField) IsSet() bool { // IsLazy reports whether a field is lazily encoded. // It is exported for testing. -func IsLazy(m pref.Message, fd pref.FieldDescriptor) bool { +func IsLazy(m protoreflect.Message, fd protoreflect.FieldDescriptor) bool { var mi *MessageInfo var p pointer switch m := m.(type) { @@ -206,7 +206,7 @@ func IsLazy(m pref.Message, fd pref.FieldDescriptor) bool { default: return false } - xd, ok := fd.(pref.ExtensionTypeDescriptor) + xd, ok := fd.(protoreflect.ExtensionTypeDescriptor) if !ok { return false } diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_field.go b/vendor/google.golang.org/protobuf/internal/impl/codec_field.go index cb4b482d1..3fadd241e 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_field.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_field.go @@ -12,9 +12,9 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/proto" - pref "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoiface" ) type errInvalidUTF8 struct{} @@ -30,7 +30,7 @@ func (errInvalidUTF8) Unwrap() error { return errors.Error } // to the appropriate field-specific function as necessary. // // The unmarshal function is set on each field individually as usual. -func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structInfo) { +func (mi *MessageInfo) initOneofFieldCoders(od protoreflect.OneofDescriptor, si structInfo) { fs := si.oneofsByName[od.Name()] ft := fs.Type oneofFields := make(map[reflect.Type]*coderFieldInfo) @@ -118,13 +118,13 @@ func (mi *MessageInfo) initOneofFieldCoders(od pref.OneofDescriptor, si structIn } } -func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs { +func makeWeakMessageFieldCoder(fd protoreflect.FieldDescriptor) pointerCoderFuncs { var once sync.Once - var messageType pref.MessageType + var messageType protoreflect.MessageType lazyInit := func() { once.Do(func() { messageName := fd.Message().FullName() - messageType, _ = preg.GlobalTypes.FindMessageByName(messageName) + messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName) }) } @@ -190,7 +190,7 @@ func makeWeakMessageFieldCoder(fd pref.FieldDescriptor) pointerCoderFuncs { } } -func makeMessageFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { +func makeMessageFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { if mi := getMessageInfo(ft); mi != nil { funcs := pointerCoderFuncs{ size: sizeMessageInfo, @@ -280,7 +280,7 @@ func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarsh if n < 0 { return out, errDecode } - o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ + o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{ Buf: v, Message: m.ProtoReflect(), }) @@ -288,27 +288,27 @@ func consumeMessage(b []byte, m proto.Message, wtyp protowire.Type, opts unmarsh return out, err } out.n = n - out.initialized = o.Flags&piface.UnmarshalInitialized != 0 + out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0 return out, nil } -func sizeMessageValue(v pref.Value, tagsize int, opts marshalOptions) int { +func sizeMessageValue(v protoreflect.Value, tagsize int, opts marshalOptions) int { m := v.Message().Interface() return sizeMessage(m, tagsize, opts) } -func appendMessageValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { +func appendMessageValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { m := v.Message().Interface() return appendMessage(b, m, wiretag, opts) } -func consumeMessageValue(b []byte, v pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) { +func consumeMessageValue(b []byte, v protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) { m := v.Message().Interface() out, err := consumeMessage(b, m, wtyp, opts) return v, out, err } -func isInitMessageValue(v pref.Value) error { +func isInitMessageValue(v protoreflect.Value) error { m := v.Message().Interface() return proto.CheckInitialized(m) } @@ -321,17 +321,17 @@ var coderMessageValue = valueCoderFuncs{ merge: mergeMessageValue, } -func sizeGroupValue(v pref.Value, tagsize int, opts marshalOptions) int { +func sizeGroupValue(v protoreflect.Value, tagsize int, opts marshalOptions) int { m := v.Message().Interface() return sizeGroup(m, tagsize, opts) } -func appendGroupValue(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { +func appendGroupValue(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { m := v.Message().Interface() return appendGroup(b, m, wiretag, opts) } -func consumeGroupValue(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) { +func consumeGroupValue(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) { m := v.Message().Interface() out, err := consumeGroup(b, m, num, wtyp, opts) return v, out, err @@ -345,7 +345,7 @@ var coderGroupValue = valueCoderFuncs{ merge: mergeMessageValue, } -func makeGroupFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { +func makeGroupFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { num := fd.Number() if mi := getMessageInfo(ft); mi != nil { funcs := pointerCoderFuncs{ @@ -424,7 +424,7 @@ func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowir if n < 0 { return out, errDecode } - o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ + o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{ Buf: b, Message: m.ProtoReflect(), }) @@ -432,11 +432,11 @@ func consumeGroup(b []byte, m proto.Message, num protowire.Number, wtyp protowir return out, err } out.n = n - out.initialized = o.Flags&piface.UnmarshalInitialized != 0 + out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0 return out, nil } -func makeMessageSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { +func makeMessageSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { if mi := getMessageInfo(ft); mi != nil { funcs := pointerCoderFuncs{ size: sizeMessageSliceInfo, @@ -555,7 +555,7 @@ func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowir return out, errDecode } mp := reflect.New(goType.Elem()) - o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ + o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{ Buf: v, Message: asMessage(mp).ProtoReflect(), }) @@ -564,7 +564,7 @@ func consumeMessageSlice(b []byte, p pointer, goType reflect.Type, wtyp protowir } p.AppendPointerSlice(pointerOfValue(mp)) out.n = n - out.initialized = o.Flags&piface.UnmarshalInitialized != 0 + out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0 return out, nil } @@ -581,7 +581,7 @@ func isInitMessageSlice(p pointer, goType reflect.Type) error { // Slices of messages -func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int { +func sizeMessageSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int { list := listv.List() n := 0 for i, llen := 0, list.Len(); i < llen; i++ { @@ -591,7 +591,7 @@ func sizeMessageSliceValue(listv pref.Value, tagsize int, opts marshalOptions) i return n } -func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { +func appendMessageSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { list := listv.List() mopts := opts.Options() for i, llen := 0, list.Len(); i < llen; i++ { @@ -608,30 +608,30 @@ func appendMessageSliceValue(b []byte, listv pref.Value, wiretag uint64, opts ma return b, nil } -func consumeMessageSliceValue(b []byte, listv pref.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) { +func consumeMessageSliceValue(b []byte, listv protoreflect.Value, _ protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) { list := listv.List() if wtyp != protowire.BytesType { - return pref.Value{}, out, errUnknown + return protoreflect.Value{}, out, errUnknown } v, n := protowire.ConsumeBytes(b) if n < 0 { - return pref.Value{}, out, errDecode + return protoreflect.Value{}, out, errDecode } m := list.NewElement() - o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ + o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{ Buf: v, Message: m.Message(), }) if err != nil { - return pref.Value{}, out, err + return protoreflect.Value{}, out, err } list.Append(m) out.n = n - out.initialized = o.Flags&piface.UnmarshalInitialized != 0 + out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0 return listv, out, nil } -func isInitMessageSliceValue(listv pref.Value) error { +func isInitMessageSliceValue(listv protoreflect.Value) error { list := listv.List() for i, llen := 0, list.Len(); i < llen; i++ { m := list.Get(i).Message().Interface() @@ -650,7 +650,7 @@ var coderMessageSliceValue = valueCoderFuncs{ merge: mergeMessageListValue, } -func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int { +func sizeGroupSliceValue(listv protoreflect.Value, tagsize int, opts marshalOptions) int { list := listv.List() n := 0 for i, llen := 0, list.Len(); i < llen; i++ { @@ -660,7 +660,7 @@ func sizeGroupSliceValue(listv pref.Value, tagsize int, opts marshalOptions) int return n } -func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { +func appendGroupSliceValue(b []byte, listv protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) { list := listv.List() mopts := opts.Options() for i, llen := 0, list.Len(); i < llen; i++ { @@ -676,26 +676,26 @@ func appendGroupSliceValue(b []byte, listv pref.Value, wiretag uint64, opts mars return b, nil } -func consumeGroupSliceValue(b []byte, listv pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ pref.Value, out unmarshalOutput, err error) { +func consumeGroupSliceValue(b []byte, listv protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (_ protoreflect.Value, out unmarshalOutput, err error) { list := listv.List() if wtyp != protowire.StartGroupType { - return pref.Value{}, out, errUnknown + return protoreflect.Value{}, out, errUnknown } b, n := protowire.ConsumeGroup(num, b) if n < 0 { - return pref.Value{}, out, errDecode + return protoreflect.Value{}, out, errDecode } m := list.NewElement() - o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ + o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{ Buf: b, Message: m.Message(), }) if err != nil { - return pref.Value{}, out, err + return protoreflect.Value{}, out, err } list.Append(m) out.n = n - out.initialized = o.Flags&piface.UnmarshalInitialized != 0 + out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0 return listv, out, nil } @@ -707,7 +707,7 @@ var coderGroupSliceValue = valueCoderFuncs{ merge: mergeMessageListValue, } -func makeGroupSliceFieldCoder(fd pref.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { +func makeGroupSliceFieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) pointerCoderFuncs { num := fd.Number() if mi := getMessageInfo(ft); mi != nil { funcs := pointerCoderFuncs{ @@ -772,7 +772,7 @@ func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire return out, errDecode } mp := reflect.New(goType.Elem()) - o, err := opts.Options().UnmarshalState(piface.UnmarshalInput{ + o, err := opts.Options().UnmarshalState(protoiface.UnmarshalInput{ Buf: b, Message: asMessage(mp).ProtoReflect(), }) @@ -781,7 +781,7 @@ func consumeGroupSlice(b []byte, p pointer, num protowire.Number, wtyp protowire } p.AppendPointerSlice(pointerOfValue(mp)) out.n = n - out.initialized = o.Flags&piface.UnmarshalInitialized != 0 + out.initialized = o.Flags&protoiface.UnmarshalInitialized != 0 return out, nil } @@ -822,8 +822,8 @@ func consumeGroupSliceInfo(b []byte, p pointer, wtyp protowire.Type, f *coderFie return out, nil } -func asMessage(v reflect.Value) pref.ProtoMessage { - if m, ok := v.Interface().(pref.ProtoMessage); ok { +func asMessage(v reflect.Value) protoreflect.ProtoMessage { + if m, ok := v.Interface().(protoreflect.ProtoMessage); ok { return m } return legacyWrapMessage(v).Interface() diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go index c1245fef4..111b9d16f 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/genid" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type mapInfo struct { @@ -19,12 +19,12 @@ type mapInfo struct { valWiretag uint64 keyFuncs valueCoderFuncs valFuncs valueCoderFuncs - keyZero pref.Value - keyKind pref.Kind + keyZero protoreflect.Value + keyKind protoreflect.Kind conv *mapConverter } -func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage *MessageInfo, funcs pointerCoderFuncs) { +func encoderFuncsForMap(fd protoreflect.FieldDescriptor, ft reflect.Type) (valueMessage *MessageInfo, funcs pointerCoderFuncs) { // TODO: Consider generating specialized map coders. keyField := fd.MapKey() valField := fd.MapValue() @@ -44,7 +44,7 @@ func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage keyKind: keyField.Kind(), conv: conv, } - if valField.Kind() == pref.MessageKind { + if valField.Kind() == protoreflect.MessageKind { valueMessage = getMessageInfo(ft.Elem()) } @@ -68,9 +68,9 @@ func encoderFuncsForMap(fd pref.FieldDescriptor, ft reflect.Type) (valueMessage }, } switch valField.Kind() { - case pref.MessageKind: + case protoreflect.MessageKind: funcs.merge = mergeMapOfMessage - case pref.BytesKind: + case protoreflect.BytesKind: funcs.merge = mergeMapOfBytes default: funcs.merge = mergeMap @@ -135,7 +135,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo err := errUnknown switch num { case genid.MapEntry_Key_field_number: - var v pref.Value + var v protoreflect.Value var o unmarshalOutput v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts) if err != nil { @@ -144,7 +144,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo key = v n = o.n case genid.MapEntry_Value_field_number: - var v pref.Value + var v protoreflect.Value var o unmarshalOutput v, o, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts) if err != nil { @@ -192,7 +192,7 @@ func consumeMapOfMessage(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi err := errUnknown switch num { case 1: - var v pref.Value + var v protoreflect.Value var o unmarshalOutput v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts) if err != nil { diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_message.go b/vendor/google.golang.org/protobuf/internal/impl/codec_message.go index cd40527ff..6b2fdbb73 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_message.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_message.go @@ -12,15 +12,15 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/order" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" ) // coderMessageInfo contains per-message information used by the fast-path functions. // This is a different type from MessageInfo to keep MessageInfo as general-purpose as // possible. type coderMessageInfo struct { - methods piface.Methods + methods protoiface.Methods orderedCoderFields []*coderFieldInfo denseCoderFields []*coderFieldInfo @@ -38,13 +38,13 @@ type coderFieldInfo struct { funcs pointerCoderFuncs // fast-path per-field functions mi *MessageInfo // field's message ft reflect.Type - validation validationInfo // information used by message validation - num pref.FieldNumber // field number - offset offset // struct field offset - wiretag uint64 // field tag (number + wire type) - tagsize int // size of the varint-encoded tag - isPointer bool // true if IsNil may be called on the struct field - isRequired bool // true if field is required + validation validationInfo // information used by message validation + num protoreflect.FieldNumber // field number + offset offset // struct field offset + wiretag uint64 // field tag (number + wire type) + tagsize int // size of the varint-encoded tag + isPointer bool // true if IsNil may be called on the struct field + isRequired bool // true if field is required } func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { @@ -125,8 +125,8 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { funcs: funcs, mi: childMessage, validation: newFieldValidationInfo(mi, si, fd, ft), - isPointer: fd.Cardinality() == pref.Repeated || fd.HasPresence(), - isRequired: fd.Cardinality() == pref.Required, + isPointer: fd.Cardinality() == protoreflect.Repeated || fd.HasPresence(), + isRequired: fd.Cardinality() == protoreflect.Required, } mi.orderedCoderFields = append(mi.orderedCoderFields, cf) mi.coderFields[cf.num] = cf @@ -149,7 +149,7 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { return mi.orderedCoderFields[i].num < mi.orderedCoderFields[j].num }) - var maxDense pref.FieldNumber + var maxDense protoreflect.FieldNumber for _, cf := range mi.orderedCoderFields { if cf.num >= 16 && cf.num >= 2*maxDense { break @@ -175,12 +175,12 @@ func (mi *MessageInfo) makeCoderMethods(t reflect.Type, si structInfo) { mi.needsInitCheck = needsInitCheck(mi.Desc) if mi.methods.Marshal == nil && mi.methods.Size == nil { - mi.methods.Flags |= piface.SupportMarshalDeterministic + mi.methods.Flags |= protoiface.SupportMarshalDeterministic mi.methods.Marshal = mi.marshal mi.methods.Size = mi.size } if mi.methods.Unmarshal == nil { - mi.methods.Flags |= piface.SupportUnmarshalDiscardUnknown + mi.methods.Flags |= protoiface.SupportUnmarshalDiscardUnknown mi.methods.Unmarshal = mi.unmarshal } if mi.methods.CheckInitialized == nil { diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go b/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go index e89971238..576dcf3aa 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_tables.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/strs" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) // pointerCoderFuncs is a set of pointer encoding functions. @@ -25,83 +25,83 @@ type pointerCoderFuncs struct { // valueCoderFuncs is a set of protoreflect.Value encoding functions. type valueCoderFuncs struct { - size func(v pref.Value, tagsize int, opts marshalOptions) int - marshal func(b []byte, v pref.Value, wiretag uint64, opts marshalOptions) ([]byte, error) - unmarshal func(b []byte, v pref.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (pref.Value, unmarshalOutput, error) - isInit func(v pref.Value) error - merge func(dst, src pref.Value, opts mergeOptions) pref.Value + size func(v protoreflect.Value, tagsize int, opts marshalOptions) int + marshal func(b []byte, v protoreflect.Value, wiretag uint64, opts marshalOptions) ([]byte, error) + unmarshal func(b []byte, v protoreflect.Value, num protowire.Number, wtyp protowire.Type, opts unmarshalOptions) (protoreflect.Value, unmarshalOutput, error) + isInit func(v protoreflect.Value) error + merge func(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value } // fieldCoder returns pointer functions for a field, used for operating on // struct fields. -func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) { +func fieldCoder(fd protoreflect.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointerCoderFuncs) { switch { case fd.IsMap(): return encoderFuncsForMap(fd, ft) - case fd.Cardinality() == pref.Repeated && !fd.IsPacked(): + case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked(): // Repeated fields (not packed). if ft.Kind() != reflect.Slice { break } ft := ft.Elem() switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: if ft.Kind() == reflect.Bool { return nil, coderBoolSlice } - case pref.EnumKind: + case protoreflect.EnumKind: if ft.Kind() == reflect.Int32 { return nil, coderEnumSlice } - case pref.Int32Kind: + case protoreflect.Int32Kind: if ft.Kind() == reflect.Int32 { return nil, coderInt32Slice } - case pref.Sint32Kind: + case protoreflect.Sint32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSint32Slice } - case pref.Uint32Kind: + case protoreflect.Uint32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderUint32Slice } - case pref.Int64Kind: + case protoreflect.Int64Kind: if ft.Kind() == reflect.Int64 { return nil, coderInt64Slice } - case pref.Sint64Kind: + case protoreflect.Sint64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSint64Slice } - case pref.Uint64Kind: + case protoreflect.Uint64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderUint64Slice } - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSfixed32Slice } - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderFixed32Slice } - case pref.FloatKind: + case protoreflect.FloatKind: if ft.Kind() == reflect.Float32 { return nil, coderFloatSlice } - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSfixed64Slice } - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderFixed64Slice } - case pref.DoubleKind: + case protoreflect.DoubleKind: if ft.Kind() == reflect.Float64 { return nil, coderDoubleSlice } - case pref.StringKind: + case protoreflect.StringKind: if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { return nil, coderStringSliceValidateUTF8 } @@ -114,19 +114,19 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { return nil, coderBytesSlice } - case pref.BytesKind: + case protoreflect.BytesKind: if ft.Kind() == reflect.String { return nil, coderStringSlice } if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { return nil, coderBytesSlice } - case pref.MessageKind: + case protoreflect.MessageKind: return getMessageInfo(ft), makeMessageSliceFieldCoder(fd, ft) - case pref.GroupKind: + case protoreflect.GroupKind: return getMessageInfo(ft), makeGroupSliceFieldCoder(fd, ft) } - case fd.Cardinality() == pref.Repeated && fd.IsPacked(): + case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked(): // Packed repeated fields. // // Only repeated fields of primitive numeric types @@ -136,128 +136,128 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer } ft := ft.Elem() switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: if ft.Kind() == reflect.Bool { return nil, coderBoolPackedSlice } - case pref.EnumKind: + case protoreflect.EnumKind: if ft.Kind() == reflect.Int32 { return nil, coderEnumPackedSlice } - case pref.Int32Kind: + case protoreflect.Int32Kind: if ft.Kind() == reflect.Int32 { return nil, coderInt32PackedSlice } - case pref.Sint32Kind: + case protoreflect.Sint32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSint32PackedSlice } - case pref.Uint32Kind: + case protoreflect.Uint32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderUint32PackedSlice } - case pref.Int64Kind: + case protoreflect.Int64Kind: if ft.Kind() == reflect.Int64 { return nil, coderInt64PackedSlice } - case pref.Sint64Kind: + case protoreflect.Sint64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSint64PackedSlice } - case pref.Uint64Kind: + case protoreflect.Uint64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderUint64PackedSlice } - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSfixed32PackedSlice } - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderFixed32PackedSlice } - case pref.FloatKind: + case protoreflect.FloatKind: if ft.Kind() == reflect.Float32 { return nil, coderFloatPackedSlice } - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSfixed64PackedSlice } - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderFixed64PackedSlice } - case pref.DoubleKind: + case protoreflect.DoubleKind: if ft.Kind() == reflect.Float64 { return nil, coderDoublePackedSlice } } - case fd.Kind() == pref.MessageKind: + case fd.Kind() == protoreflect.MessageKind: return getMessageInfo(ft), makeMessageFieldCoder(fd, ft) - case fd.Kind() == pref.GroupKind: + case fd.Kind() == protoreflect.GroupKind: return getMessageInfo(ft), makeGroupFieldCoder(fd, ft) - case fd.Syntax() == pref.Proto3 && fd.ContainingOneof() == nil: + case fd.Syntax() == protoreflect.Proto3 && fd.ContainingOneof() == nil: // Populated oneof fields always encode even if set to the zero value, // which normally are not encoded in proto3. switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: if ft.Kind() == reflect.Bool { return nil, coderBoolNoZero } - case pref.EnumKind: + case protoreflect.EnumKind: if ft.Kind() == reflect.Int32 { return nil, coderEnumNoZero } - case pref.Int32Kind: + case protoreflect.Int32Kind: if ft.Kind() == reflect.Int32 { return nil, coderInt32NoZero } - case pref.Sint32Kind: + case protoreflect.Sint32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSint32NoZero } - case pref.Uint32Kind: + case protoreflect.Uint32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderUint32NoZero } - case pref.Int64Kind: + case protoreflect.Int64Kind: if ft.Kind() == reflect.Int64 { return nil, coderInt64NoZero } - case pref.Sint64Kind: + case protoreflect.Sint64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSint64NoZero } - case pref.Uint64Kind: + case protoreflect.Uint64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderUint64NoZero } - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSfixed32NoZero } - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderFixed32NoZero } - case pref.FloatKind: + case protoreflect.FloatKind: if ft.Kind() == reflect.Float32 { return nil, coderFloatNoZero } - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSfixed64NoZero } - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderFixed64NoZero } - case pref.DoubleKind: + case protoreflect.DoubleKind: if ft.Kind() == reflect.Float64 { return nil, coderDoubleNoZero } - case pref.StringKind: + case protoreflect.StringKind: if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { return nil, coderStringNoZeroValidateUTF8 } @@ -270,7 +270,7 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { return nil, coderBytesNoZero } - case pref.BytesKind: + case protoreflect.BytesKind: if ft.Kind() == reflect.String { return nil, coderStringNoZero } @@ -281,133 +281,133 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer case ft.Kind() == reflect.Ptr: ft := ft.Elem() switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: if ft.Kind() == reflect.Bool { return nil, coderBoolPtr } - case pref.EnumKind: + case protoreflect.EnumKind: if ft.Kind() == reflect.Int32 { return nil, coderEnumPtr } - case pref.Int32Kind: + case protoreflect.Int32Kind: if ft.Kind() == reflect.Int32 { return nil, coderInt32Ptr } - case pref.Sint32Kind: + case protoreflect.Sint32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSint32Ptr } - case pref.Uint32Kind: + case protoreflect.Uint32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderUint32Ptr } - case pref.Int64Kind: + case protoreflect.Int64Kind: if ft.Kind() == reflect.Int64 { return nil, coderInt64Ptr } - case pref.Sint64Kind: + case protoreflect.Sint64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSint64Ptr } - case pref.Uint64Kind: + case protoreflect.Uint64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderUint64Ptr } - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSfixed32Ptr } - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderFixed32Ptr } - case pref.FloatKind: + case protoreflect.FloatKind: if ft.Kind() == reflect.Float32 { return nil, coderFloatPtr } - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSfixed64Ptr } - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderFixed64Ptr } - case pref.DoubleKind: + case protoreflect.DoubleKind: if ft.Kind() == reflect.Float64 { return nil, coderDoublePtr } - case pref.StringKind: + case protoreflect.StringKind: if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { return nil, coderStringPtrValidateUTF8 } if ft.Kind() == reflect.String { return nil, coderStringPtr } - case pref.BytesKind: + case protoreflect.BytesKind: if ft.Kind() == reflect.String { return nil, coderStringPtr } } default: switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: if ft.Kind() == reflect.Bool { return nil, coderBool } - case pref.EnumKind: + case protoreflect.EnumKind: if ft.Kind() == reflect.Int32 { return nil, coderEnum } - case pref.Int32Kind: + case protoreflect.Int32Kind: if ft.Kind() == reflect.Int32 { return nil, coderInt32 } - case pref.Sint32Kind: + case protoreflect.Sint32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSint32 } - case pref.Uint32Kind: + case protoreflect.Uint32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderUint32 } - case pref.Int64Kind: + case protoreflect.Int64Kind: if ft.Kind() == reflect.Int64 { return nil, coderInt64 } - case pref.Sint64Kind: + case protoreflect.Sint64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSint64 } - case pref.Uint64Kind: + case protoreflect.Uint64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderUint64 } - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: if ft.Kind() == reflect.Int32 { return nil, coderSfixed32 } - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: if ft.Kind() == reflect.Uint32 { return nil, coderFixed32 } - case pref.FloatKind: + case protoreflect.FloatKind: if ft.Kind() == reflect.Float32 { return nil, coderFloat } - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: if ft.Kind() == reflect.Int64 { return nil, coderSfixed64 } - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: if ft.Kind() == reflect.Uint64 { return nil, coderFixed64 } - case pref.DoubleKind: + case protoreflect.DoubleKind: if ft.Kind() == reflect.Float64 { return nil, coderDouble } - case pref.StringKind: + case protoreflect.StringKind: if ft.Kind() == reflect.String && strs.EnforceUTF8(fd) { return nil, coderStringValidateUTF8 } @@ -420,7 +420,7 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer if ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 { return nil, coderBytes } - case pref.BytesKind: + case protoreflect.BytesKind: if ft.Kind() == reflect.String { return nil, coderString } @@ -434,122 +434,122 @@ func fieldCoder(fd pref.FieldDescriptor, ft reflect.Type) (*MessageInfo, pointer // encoderFuncsForValue returns value functions for a field, used for // extension values and map encoding. -func encoderFuncsForValue(fd pref.FieldDescriptor) valueCoderFuncs { +func encoderFuncsForValue(fd protoreflect.FieldDescriptor) valueCoderFuncs { switch { - case fd.Cardinality() == pref.Repeated && !fd.IsPacked(): + case fd.Cardinality() == protoreflect.Repeated && !fd.IsPacked(): switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: return coderBoolSliceValue - case pref.EnumKind: + case protoreflect.EnumKind: return coderEnumSliceValue - case pref.Int32Kind: + case protoreflect.Int32Kind: return coderInt32SliceValue - case pref.Sint32Kind: + case protoreflect.Sint32Kind: return coderSint32SliceValue - case pref.Uint32Kind: + case protoreflect.Uint32Kind: return coderUint32SliceValue - case pref.Int64Kind: + case protoreflect.Int64Kind: return coderInt64SliceValue - case pref.Sint64Kind: + case protoreflect.Sint64Kind: return coderSint64SliceValue - case pref.Uint64Kind: + case protoreflect.Uint64Kind: return coderUint64SliceValue - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: return coderSfixed32SliceValue - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: return coderFixed32SliceValue - case pref.FloatKind: + case protoreflect.FloatKind: return coderFloatSliceValue - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: return coderSfixed64SliceValue - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: return coderFixed64SliceValue - case pref.DoubleKind: + case protoreflect.DoubleKind: return coderDoubleSliceValue - case pref.StringKind: + case protoreflect.StringKind: // We don't have a UTF-8 validating coder for repeated string fields. // Value coders are used for extensions and maps. // Extensions are never proto3, and maps never contain lists. return coderStringSliceValue - case pref.BytesKind: + case protoreflect.BytesKind: return coderBytesSliceValue - case pref.MessageKind: + case protoreflect.MessageKind: return coderMessageSliceValue - case pref.GroupKind: + case protoreflect.GroupKind: return coderGroupSliceValue } - case fd.Cardinality() == pref.Repeated && fd.IsPacked(): + case fd.Cardinality() == protoreflect.Repeated && fd.IsPacked(): switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: return coderBoolPackedSliceValue - case pref.EnumKind: + case protoreflect.EnumKind: return coderEnumPackedSliceValue - case pref.Int32Kind: + case protoreflect.Int32Kind: return coderInt32PackedSliceValue - case pref.Sint32Kind: + case protoreflect.Sint32Kind: return coderSint32PackedSliceValue - case pref.Uint32Kind: + case protoreflect.Uint32Kind: return coderUint32PackedSliceValue - case pref.Int64Kind: + case protoreflect.Int64Kind: return coderInt64PackedSliceValue - case pref.Sint64Kind: + case protoreflect.Sint64Kind: return coderSint64PackedSliceValue - case pref.Uint64Kind: + case protoreflect.Uint64Kind: return coderUint64PackedSliceValue - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: return coderSfixed32PackedSliceValue - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: return coderFixed32PackedSliceValue - case pref.FloatKind: + case protoreflect.FloatKind: return coderFloatPackedSliceValue - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: return coderSfixed64PackedSliceValue - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: return coderFixed64PackedSliceValue - case pref.DoubleKind: + case protoreflect.DoubleKind: return coderDoublePackedSliceValue } default: switch fd.Kind() { default: - case pref.BoolKind: + case protoreflect.BoolKind: return coderBoolValue - case pref.EnumKind: + case protoreflect.EnumKind: return coderEnumValue - case pref.Int32Kind: + case protoreflect.Int32Kind: return coderInt32Value - case pref.Sint32Kind: + case protoreflect.Sint32Kind: return coderSint32Value - case pref.Uint32Kind: + case protoreflect.Uint32Kind: return coderUint32Value - case pref.Int64Kind: + case protoreflect.Int64Kind: return coderInt64Value - case pref.Sint64Kind: + case protoreflect.Sint64Kind: return coderSint64Value - case pref.Uint64Kind: + case protoreflect.Uint64Kind: return coderUint64Value - case pref.Sfixed32Kind: + case protoreflect.Sfixed32Kind: return coderSfixed32Value - case pref.Fixed32Kind: + case protoreflect.Fixed32Kind: return coderFixed32Value - case pref.FloatKind: + case protoreflect.FloatKind: return coderFloatValue - case pref.Sfixed64Kind: + case protoreflect.Sfixed64Kind: return coderSfixed64Value - case pref.Fixed64Kind: + case protoreflect.Fixed64Kind: return coderFixed64Value - case pref.DoubleKind: + case protoreflect.DoubleKind: return coderDoubleValue - case pref.StringKind: + case protoreflect.StringKind: if strs.EnforceUTF8(fd) { return coderStringValueValidateUTF8 } return coderStringValue - case pref.BytesKind: + case protoreflect.BytesKind: return coderBytesValue - case pref.MessageKind: + case protoreflect.MessageKind: return coderMessageValue - case pref.GroupKind: + case protoreflect.GroupKind: return coderGroupValue } } diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert.go b/vendor/google.golang.org/protobuf/internal/impl/convert.go index acd61bb50..11a6128ba 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/convert.go +++ b/vendor/google.golang.org/protobuf/internal/impl/convert.go @@ -8,7 +8,7 @@ import ( "fmt" "reflect" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) // unwrapper unwraps the value to the underlying value. @@ -20,13 +20,13 @@ type unwrapper interface { // A Converter coverts to/from Go reflect.Value types and protobuf protoreflect.Value types. type Converter interface { // PBValueOf converts a reflect.Value to a protoreflect.Value. - PBValueOf(reflect.Value) pref.Value + PBValueOf(reflect.Value) protoreflect.Value // GoValueOf converts a protoreflect.Value to a reflect.Value. - GoValueOf(pref.Value) reflect.Value + GoValueOf(protoreflect.Value) reflect.Value // IsValidPB returns whether a protoreflect.Value is compatible with this type. - IsValidPB(pref.Value) bool + IsValidPB(protoreflect.Value) bool // IsValidGo returns whether a reflect.Value is compatible with this type. IsValidGo(reflect.Value) bool @@ -34,12 +34,12 @@ type Converter interface { // New returns a new field value. // For scalars, it returns the default value of the field. // For composite types, it returns a new mutable value. - New() pref.Value + New() protoreflect.Value // Zero returns a new field value. // For scalars, it returns the default value of the field. // For composite types, it returns an immutable, empty value. - Zero() pref.Value + Zero() protoreflect.Value } // NewConverter matches a Go type with a protobuf field and returns a Converter @@ -50,7 +50,7 @@ type Converter interface { // This matcher deliberately supports a wider range of Go types than what // protoc-gen-go historically generated to be able to automatically wrap some // v1 messages generated by other forks of protoc-gen-go. -func NewConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { +func NewConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter { switch { case fd.IsList(): return newListConverter(t, fd) @@ -76,68 +76,68 @@ var ( ) var ( - boolZero = pref.ValueOfBool(false) - int32Zero = pref.ValueOfInt32(0) - int64Zero = pref.ValueOfInt64(0) - uint32Zero = pref.ValueOfUint32(0) - uint64Zero = pref.ValueOfUint64(0) - float32Zero = pref.ValueOfFloat32(0) - float64Zero = pref.ValueOfFloat64(0) - stringZero = pref.ValueOfString("") - bytesZero = pref.ValueOfBytes(nil) + boolZero = protoreflect.ValueOfBool(false) + int32Zero = protoreflect.ValueOfInt32(0) + int64Zero = protoreflect.ValueOfInt64(0) + uint32Zero = protoreflect.ValueOfUint32(0) + uint64Zero = protoreflect.ValueOfUint64(0) + float32Zero = protoreflect.ValueOfFloat32(0) + float64Zero = protoreflect.ValueOfFloat64(0) + stringZero = protoreflect.ValueOfString("") + bytesZero = protoreflect.ValueOfBytes(nil) ) -func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { - defVal := func(fd pref.FieldDescriptor, zero pref.Value) pref.Value { - if fd.Cardinality() == pref.Repeated { +func newSingularConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter { + defVal := func(fd protoreflect.FieldDescriptor, zero protoreflect.Value) protoreflect.Value { + if fd.Cardinality() == protoreflect.Repeated { // Default isn't defined for repeated fields. return zero } return fd.Default() } switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: if t.Kind() == reflect.Bool { return &boolConverter{t, defVal(fd, boolZero)} } - case pref.Int32Kind, pref.Sint32Kind, pref.Sfixed32Kind: + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: if t.Kind() == reflect.Int32 { return &int32Converter{t, defVal(fd, int32Zero)} } - case pref.Int64Kind, pref.Sint64Kind, pref.Sfixed64Kind: + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: if t.Kind() == reflect.Int64 { return &int64Converter{t, defVal(fd, int64Zero)} } - case pref.Uint32Kind, pref.Fixed32Kind: + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: if t.Kind() == reflect.Uint32 { return &uint32Converter{t, defVal(fd, uint32Zero)} } - case pref.Uint64Kind, pref.Fixed64Kind: + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: if t.Kind() == reflect.Uint64 { return &uint64Converter{t, defVal(fd, uint64Zero)} } - case pref.FloatKind: + case protoreflect.FloatKind: if t.Kind() == reflect.Float32 { return &float32Converter{t, defVal(fd, float32Zero)} } - case pref.DoubleKind: + case protoreflect.DoubleKind: if t.Kind() == reflect.Float64 { return &float64Converter{t, defVal(fd, float64Zero)} } - case pref.StringKind: + case protoreflect.StringKind: if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { return &stringConverter{t, defVal(fd, stringZero)} } - case pref.BytesKind: + case protoreflect.BytesKind: if t.Kind() == reflect.String || (t.Kind() == reflect.Slice && t.Elem() == byteType) { return &bytesConverter{t, defVal(fd, bytesZero)} } - case pref.EnumKind: + case protoreflect.EnumKind: // Handle enums, which must be a named int32 type. if t.Kind() == reflect.Int32 { return newEnumConverter(t, fd) } - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: return newMessageConverter(t) } panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) @@ -145,184 +145,184 @@ func newSingularConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { type boolConverter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *boolConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *boolConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfBool(v.Bool()) + return protoreflect.ValueOfBool(v.Bool()) } -func (c *boolConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *boolConverter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(v.Bool()).Convert(c.goType) } -func (c *boolConverter) IsValidPB(v pref.Value) bool { +func (c *boolConverter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(bool) return ok } func (c *boolConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *boolConverter) New() pref.Value { return c.def } -func (c *boolConverter) Zero() pref.Value { return c.def } +func (c *boolConverter) New() protoreflect.Value { return c.def } +func (c *boolConverter) Zero() protoreflect.Value { return c.def } type int32Converter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *int32Converter) PBValueOf(v reflect.Value) pref.Value { +func (c *int32Converter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfInt32(int32(v.Int())) + return protoreflect.ValueOfInt32(int32(v.Int())) } -func (c *int32Converter) GoValueOf(v pref.Value) reflect.Value { +func (c *int32Converter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(int32(v.Int())).Convert(c.goType) } -func (c *int32Converter) IsValidPB(v pref.Value) bool { +func (c *int32Converter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(int32) return ok } func (c *int32Converter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *int32Converter) New() pref.Value { return c.def } -func (c *int32Converter) Zero() pref.Value { return c.def } +func (c *int32Converter) New() protoreflect.Value { return c.def } +func (c *int32Converter) Zero() protoreflect.Value { return c.def } type int64Converter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *int64Converter) PBValueOf(v reflect.Value) pref.Value { +func (c *int64Converter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfInt64(int64(v.Int())) + return protoreflect.ValueOfInt64(int64(v.Int())) } -func (c *int64Converter) GoValueOf(v pref.Value) reflect.Value { +func (c *int64Converter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(int64(v.Int())).Convert(c.goType) } -func (c *int64Converter) IsValidPB(v pref.Value) bool { +func (c *int64Converter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(int64) return ok } func (c *int64Converter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *int64Converter) New() pref.Value { return c.def } -func (c *int64Converter) Zero() pref.Value { return c.def } +func (c *int64Converter) New() protoreflect.Value { return c.def } +func (c *int64Converter) Zero() protoreflect.Value { return c.def } type uint32Converter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *uint32Converter) PBValueOf(v reflect.Value) pref.Value { +func (c *uint32Converter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfUint32(uint32(v.Uint())) + return protoreflect.ValueOfUint32(uint32(v.Uint())) } -func (c *uint32Converter) GoValueOf(v pref.Value) reflect.Value { +func (c *uint32Converter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(uint32(v.Uint())).Convert(c.goType) } -func (c *uint32Converter) IsValidPB(v pref.Value) bool { +func (c *uint32Converter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(uint32) return ok } func (c *uint32Converter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *uint32Converter) New() pref.Value { return c.def } -func (c *uint32Converter) Zero() pref.Value { return c.def } +func (c *uint32Converter) New() protoreflect.Value { return c.def } +func (c *uint32Converter) Zero() protoreflect.Value { return c.def } type uint64Converter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *uint64Converter) PBValueOf(v reflect.Value) pref.Value { +func (c *uint64Converter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfUint64(uint64(v.Uint())) + return protoreflect.ValueOfUint64(uint64(v.Uint())) } -func (c *uint64Converter) GoValueOf(v pref.Value) reflect.Value { +func (c *uint64Converter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(uint64(v.Uint())).Convert(c.goType) } -func (c *uint64Converter) IsValidPB(v pref.Value) bool { +func (c *uint64Converter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(uint64) return ok } func (c *uint64Converter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *uint64Converter) New() pref.Value { return c.def } -func (c *uint64Converter) Zero() pref.Value { return c.def } +func (c *uint64Converter) New() protoreflect.Value { return c.def } +func (c *uint64Converter) Zero() protoreflect.Value { return c.def } type float32Converter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *float32Converter) PBValueOf(v reflect.Value) pref.Value { +func (c *float32Converter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfFloat32(float32(v.Float())) + return protoreflect.ValueOfFloat32(float32(v.Float())) } -func (c *float32Converter) GoValueOf(v pref.Value) reflect.Value { +func (c *float32Converter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(float32(v.Float())).Convert(c.goType) } -func (c *float32Converter) IsValidPB(v pref.Value) bool { +func (c *float32Converter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(float32) return ok } func (c *float32Converter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *float32Converter) New() pref.Value { return c.def } -func (c *float32Converter) Zero() pref.Value { return c.def } +func (c *float32Converter) New() protoreflect.Value { return c.def } +func (c *float32Converter) Zero() protoreflect.Value { return c.def } type float64Converter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *float64Converter) PBValueOf(v reflect.Value) pref.Value { +func (c *float64Converter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfFloat64(float64(v.Float())) + return protoreflect.ValueOfFloat64(float64(v.Float())) } -func (c *float64Converter) GoValueOf(v pref.Value) reflect.Value { +func (c *float64Converter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(float64(v.Float())).Convert(c.goType) } -func (c *float64Converter) IsValidPB(v pref.Value) bool { +func (c *float64Converter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(float64) return ok } func (c *float64Converter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *float64Converter) New() pref.Value { return c.def } -func (c *float64Converter) Zero() pref.Value { return c.def } +func (c *float64Converter) New() protoreflect.Value { return c.def } +func (c *float64Converter) Zero() protoreflect.Value { return c.def } type stringConverter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *stringConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *stringConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfString(v.Convert(stringType).String()) + return protoreflect.ValueOfString(v.Convert(stringType).String()) } -func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *stringConverter) GoValueOf(v protoreflect.Value) reflect.Value { // pref.Value.String never panics, so we go through an interface // conversion here to check the type. s := v.Interface().(string) @@ -331,71 +331,71 @@ func (c *stringConverter) GoValueOf(v pref.Value) reflect.Value { } return reflect.ValueOf(s).Convert(c.goType) } -func (c *stringConverter) IsValidPB(v pref.Value) bool { +func (c *stringConverter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().(string) return ok } func (c *stringConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *stringConverter) New() pref.Value { return c.def } -func (c *stringConverter) Zero() pref.Value { return c.def } +func (c *stringConverter) New() protoreflect.Value { return c.def } +func (c *stringConverter) Zero() protoreflect.Value { return c.def } type bytesConverter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func (c *bytesConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *bytesConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } if c.goType.Kind() == reflect.String && v.Len() == 0 { - return pref.ValueOfBytes(nil) // ensure empty string is []byte(nil) + return protoreflect.ValueOfBytes(nil) // ensure empty string is []byte(nil) } - return pref.ValueOfBytes(v.Convert(bytesType).Bytes()) + return protoreflect.ValueOfBytes(v.Convert(bytesType).Bytes()) } -func (c *bytesConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *bytesConverter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(v.Bytes()).Convert(c.goType) } -func (c *bytesConverter) IsValidPB(v pref.Value) bool { +func (c *bytesConverter) IsValidPB(v protoreflect.Value) bool { _, ok := v.Interface().([]byte) return ok } func (c *bytesConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *bytesConverter) New() pref.Value { return c.def } -func (c *bytesConverter) Zero() pref.Value { return c.def } +func (c *bytesConverter) New() protoreflect.Value { return c.def } +func (c *bytesConverter) Zero() protoreflect.Value { return c.def } type enumConverter struct { goType reflect.Type - def pref.Value + def protoreflect.Value } -func newEnumConverter(goType reflect.Type, fd pref.FieldDescriptor) Converter { - var def pref.Value - if fd.Cardinality() == pref.Repeated { - def = pref.ValueOfEnum(fd.Enum().Values().Get(0).Number()) +func newEnumConverter(goType reflect.Type, fd protoreflect.FieldDescriptor) Converter { + var def protoreflect.Value + if fd.Cardinality() == protoreflect.Repeated { + def = protoreflect.ValueOfEnum(fd.Enum().Values().Get(0).Number()) } else { def = fd.Default() } return &enumConverter{goType, def} } -func (c *enumConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *enumConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfEnum(pref.EnumNumber(v.Int())) + return protoreflect.ValueOfEnum(protoreflect.EnumNumber(v.Int())) } -func (c *enumConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *enumConverter) GoValueOf(v protoreflect.Value) reflect.Value { return reflect.ValueOf(v.Enum()).Convert(c.goType) } -func (c *enumConverter) IsValidPB(v pref.Value) bool { - _, ok := v.Interface().(pref.EnumNumber) +func (c *enumConverter) IsValidPB(v protoreflect.Value) bool { + _, ok := v.Interface().(protoreflect.EnumNumber) return ok } @@ -403,11 +403,11 @@ func (c *enumConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *enumConverter) New() pref.Value { +func (c *enumConverter) New() protoreflect.Value { return c.def } -func (c *enumConverter) Zero() pref.Value { +func (c *enumConverter) Zero() protoreflect.Value { return c.def } @@ -419,7 +419,7 @@ func newMessageConverter(goType reflect.Type) Converter { return &messageConverter{goType} } -func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *messageConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } @@ -430,13 +430,13 @@ func (c *messageConverter) PBValueOf(v reflect.Value) pref.Value { v = reflect.Zero(reflect.PtrTo(v.Type())) } } - if m, ok := v.Interface().(pref.ProtoMessage); ok { - return pref.ValueOfMessage(m.ProtoReflect()) + if m, ok := v.Interface().(protoreflect.ProtoMessage); ok { + return protoreflect.ValueOfMessage(m.ProtoReflect()) } - return pref.ValueOfMessage(legacyWrapMessage(v)) + return protoreflect.ValueOfMessage(legacyWrapMessage(v)) } -func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *messageConverter) GoValueOf(v protoreflect.Value) reflect.Value { m := v.Message() var rv reflect.Value if u, ok := m.(unwrapper); ok { @@ -460,7 +460,7 @@ func (c *messageConverter) GoValueOf(v pref.Value) reflect.Value { return rv } -func (c *messageConverter) IsValidPB(v pref.Value) bool { +func (c *messageConverter) IsValidPB(v protoreflect.Value) bool { m := v.Message() var rv reflect.Value if u, ok := m.(unwrapper); ok { @@ -478,14 +478,14 @@ func (c *messageConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *messageConverter) New() pref.Value { +func (c *messageConverter) New() protoreflect.Value { if c.isNonPointer() { return c.PBValueOf(reflect.New(c.goType).Elem()) } return c.PBValueOf(reflect.New(c.goType.Elem())) } -func (c *messageConverter) Zero() pref.Value { +func (c *messageConverter) Zero() protoreflect.Value { return c.PBValueOf(reflect.Zero(c.goType)) } diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert_list.go b/vendor/google.golang.org/protobuf/internal/impl/convert_list.go index 6fccab520..f89136516 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/convert_list.go +++ b/vendor/google.golang.org/protobuf/internal/impl/convert_list.go @@ -8,10 +8,10 @@ import ( "fmt" "reflect" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) -func newListConverter(t reflect.Type, fd pref.FieldDescriptor) Converter { +func newListConverter(t reflect.Type, fd protoreflect.FieldDescriptor) Converter { switch { case t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Slice: return &listPtrConverter{t, newSingularConverter(t.Elem().Elem(), fd)} @@ -26,16 +26,16 @@ type listConverter struct { c Converter } -func (c *listConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *listConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } pv := reflect.New(c.goType) pv.Elem().Set(v) - return pref.ValueOfList(&listReflect{pv, c.c}) + return protoreflect.ValueOfList(&listReflect{pv, c.c}) } -func (c *listConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *listConverter) GoValueOf(v protoreflect.Value) reflect.Value { rv := v.List().(*listReflect).v if rv.IsNil() { return reflect.Zero(c.goType) @@ -43,7 +43,7 @@ func (c *listConverter) GoValueOf(v pref.Value) reflect.Value { return rv.Elem() } -func (c *listConverter) IsValidPB(v pref.Value) bool { +func (c *listConverter) IsValidPB(v protoreflect.Value) bool { list, ok := v.Interface().(*listReflect) if !ok { return false @@ -55,12 +55,12 @@ func (c *listConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *listConverter) New() pref.Value { - return pref.ValueOfList(&listReflect{reflect.New(c.goType), c.c}) +func (c *listConverter) New() protoreflect.Value { + return protoreflect.ValueOfList(&listReflect{reflect.New(c.goType), c.c}) } -func (c *listConverter) Zero() pref.Value { - return pref.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c}) +func (c *listConverter) Zero() protoreflect.Value { + return protoreflect.ValueOfList(&listReflect{reflect.Zero(reflect.PtrTo(c.goType)), c.c}) } type listPtrConverter struct { @@ -68,18 +68,18 @@ type listPtrConverter struct { c Converter } -func (c *listPtrConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *listPtrConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfList(&listReflect{v, c.c}) + return protoreflect.ValueOfList(&listReflect{v, c.c}) } -func (c *listPtrConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *listPtrConverter) GoValueOf(v protoreflect.Value) reflect.Value { return v.List().(*listReflect).v } -func (c *listPtrConverter) IsValidPB(v pref.Value) bool { +func (c *listPtrConverter) IsValidPB(v protoreflect.Value) bool { list, ok := v.Interface().(*listReflect) if !ok { return false @@ -91,11 +91,11 @@ func (c *listPtrConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *listPtrConverter) New() pref.Value { +func (c *listPtrConverter) New() protoreflect.Value { return c.PBValueOf(reflect.New(c.goType.Elem())) } -func (c *listPtrConverter) Zero() pref.Value { +func (c *listPtrConverter) Zero() protoreflect.Value { return c.PBValueOf(reflect.Zero(c.goType)) } @@ -110,16 +110,16 @@ func (ls *listReflect) Len() int { } return ls.v.Elem().Len() } -func (ls *listReflect) Get(i int) pref.Value { +func (ls *listReflect) Get(i int) protoreflect.Value { return ls.conv.PBValueOf(ls.v.Elem().Index(i)) } -func (ls *listReflect) Set(i int, v pref.Value) { +func (ls *listReflect) Set(i int, v protoreflect.Value) { ls.v.Elem().Index(i).Set(ls.conv.GoValueOf(v)) } -func (ls *listReflect) Append(v pref.Value) { +func (ls *listReflect) Append(v protoreflect.Value) { ls.v.Elem().Set(reflect.Append(ls.v.Elem(), ls.conv.GoValueOf(v))) } -func (ls *listReflect) AppendMutable() pref.Value { +func (ls *listReflect) AppendMutable() protoreflect.Value { if _, ok := ls.conv.(*messageConverter); !ok { panic("invalid AppendMutable on list with non-message type") } @@ -130,7 +130,7 @@ func (ls *listReflect) AppendMutable() pref.Value { func (ls *listReflect) Truncate(i int) { ls.v.Elem().Set(ls.v.Elem().Slice(0, i)) } -func (ls *listReflect) NewElement() pref.Value { +func (ls *listReflect) NewElement() protoreflect.Value { return ls.conv.New() } func (ls *listReflect) IsValid() bool { diff --git a/vendor/google.golang.org/protobuf/internal/impl/convert_map.go b/vendor/google.golang.org/protobuf/internal/impl/convert_map.go index de06b2593..f30b0a057 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/convert_map.go +++ b/vendor/google.golang.org/protobuf/internal/impl/convert_map.go @@ -8,7 +8,7 @@ import ( "fmt" "reflect" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type mapConverter struct { @@ -16,7 +16,7 @@ type mapConverter struct { keyConv, valConv Converter } -func newMapConverter(t reflect.Type, fd pref.FieldDescriptor) *mapConverter { +func newMapConverter(t reflect.Type, fd protoreflect.FieldDescriptor) *mapConverter { if t.Kind() != reflect.Map { panic(fmt.Sprintf("invalid Go type %v for field %v", t, fd.FullName())) } @@ -27,18 +27,18 @@ func newMapConverter(t reflect.Type, fd pref.FieldDescriptor) *mapConverter { } } -func (c *mapConverter) PBValueOf(v reflect.Value) pref.Value { +func (c *mapConverter) PBValueOf(v reflect.Value) protoreflect.Value { if v.Type() != c.goType { panic(fmt.Sprintf("invalid type: got %v, want %v", v.Type(), c.goType)) } - return pref.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv}) + return protoreflect.ValueOfMap(&mapReflect{v, c.keyConv, c.valConv}) } -func (c *mapConverter) GoValueOf(v pref.Value) reflect.Value { +func (c *mapConverter) GoValueOf(v protoreflect.Value) reflect.Value { return v.Map().(*mapReflect).v } -func (c *mapConverter) IsValidPB(v pref.Value) bool { +func (c *mapConverter) IsValidPB(v protoreflect.Value) bool { mapv, ok := v.Interface().(*mapReflect) if !ok { return false @@ -50,11 +50,11 @@ func (c *mapConverter) IsValidGo(v reflect.Value) bool { return v.IsValid() && v.Type() == c.goType } -func (c *mapConverter) New() pref.Value { +func (c *mapConverter) New() protoreflect.Value { return c.PBValueOf(reflect.MakeMap(c.goType)) } -func (c *mapConverter) Zero() pref.Value { +func (c *mapConverter) Zero() protoreflect.Value { return c.PBValueOf(reflect.Zero(c.goType)) } @@ -67,29 +67,29 @@ type mapReflect struct { func (ms *mapReflect) Len() int { return ms.v.Len() } -func (ms *mapReflect) Has(k pref.MapKey) bool { +func (ms *mapReflect) Has(k protoreflect.MapKey) bool { rk := ms.keyConv.GoValueOf(k.Value()) rv := ms.v.MapIndex(rk) return rv.IsValid() } -func (ms *mapReflect) Get(k pref.MapKey) pref.Value { +func (ms *mapReflect) Get(k protoreflect.MapKey) protoreflect.Value { rk := ms.keyConv.GoValueOf(k.Value()) rv := ms.v.MapIndex(rk) if !rv.IsValid() { - return pref.Value{} + return protoreflect.Value{} } return ms.valConv.PBValueOf(rv) } -func (ms *mapReflect) Set(k pref.MapKey, v pref.Value) { +func (ms *mapReflect) Set(k protoreflect.MapKey, v protoreflect.Value) { rk := ms.keyConv.GoValueOf(k.Value()) rv := ms.valConv.GoValueOf(v) ms.v.SetMapIndex(rk, rv) } -func (ms *mapReflect) Clear(k pref.MapKey) { +func (ms *mapReflect) Clear(k protoreflect.MapKey) { rk := ms.keyConv.GoValueOf(k.Value()) ms.v.SetMapIndex(rk, reflect.Value{}) } -func (ms *mapReflect) Mutable(k pref.MapKey) pref.Value { +func (ms *mapReflect) Mutable(k protoreflect.MapKey) protoreflect.Value { if _, ok := ms.valConv.(*messageConverter); !ok { panic("invalid Mutable on map with non-message value type") } @@ -100,7 +100,7 @@ func (ms *mapReflect) Mutable(k pref.MapKey) pref.Value { } return v } -func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) { +func (ms *mapReflect) Range(f func(protoreflect.MapKey, protoreflect.Value) bool) { iter := mapRange(ms.v) for iter.Next() { k := ms.keyConv.PBValueOf(iter.Key()).MapKey() @@ -110,7 +110,7 @@ func (ms *mapReflect) Range(f func(pref.MapKey, pref.Value) bool) { } } } -func (ms *mapReflect) NewValue() pref.Value { +func (ms *mapReflect) NewValue() protoreflect.Value { return ms.valConv.New() } func (ms *mapReflect) IsValid() bool { diff --git a/vendor/google.golang.org/protobuf/internal/impl/decode.go b/vendor/google.golang.org/protobuf/internal/impl/decode.go index c65b0325c..cda0520c2 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/decode.go +++ b/vendor/google.golang.org/protobuf/internal/impl/decode.go @@ -12,9 +12,8 @@ import ( "google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/reflect/protoregistry" "google.golang.org/protobuf/runtime/protoiface" - piface "google.golang.org/protobuf/runtime/protoiface" ) var errDecode = errors.New("cannot parse invalid wire-format data") @@ -38,14 +37,16 @@ func (o unmarshalOptions) Options() proto.UnmarshalOptions { } } -func (o unmarshalOptions) DiscardUnknown() bool { return o.flags&piface.UnmarshalDiscardUnknown != 0 } +func (o unmarshalOptions) DiscardUnknown() bool { + return o.flags&protoiface.UnmarshalDiscardUnknown != 0 +} func (o unmarshalOptions) IsDefault() bool { - return o.flags == 0 && o.resolver == preg.GlobalTypes + return o.flags == 0 && o.resolver == protoregistry.GlobalTypes } var lazyUnmarshalOptions = unmarshalOptions{ - resolver: preg.GlobalTypes, + resolver: protoregistry.GlobalTypes, depth: protowire.DefaultRecursionLimit, } @@ -55,7 +56,7 @@ type unmarshalOutput struct { } // unmarshal is protoreflect.Methods.Unmarshal. -func (mi *MessageInfo) unmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) { +func (mi *MessageInfo) unmarshal(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { var p pointer if ms, ok := in.Message.(*messageState); ok { p = ms.pointer() @@ -67,11 +68,11 @@ func (mi *MessageInfo) unmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutp resolver: in.Resolver, depth: in.Depth, }) - var flags piface.UnmarshalOutputFlags + var flags protoiface.UnmarshalOutputFlags if out.initialized { - flags |= piface.UnmarshalInitialized + flags |= protoiface.UnmarshalInitialized } - return piface.UnmarshalOutput{ + return protoiface.UnmarshalOutput{ Flags: flags, }, err } @@ -210,7 +211,7 @@ func (mi *MessageInfo) unmarshalExtension(b []byte, num protowire.Number, wtyp p var err error xt, err = opts.resolver.FindExtensionByNumber(mi.Desc.FullName(), num) if err != nil { - if err == preg.NotFound { + if err == protoregistry.NotFound { return out, errUnknown } return out, errors.New("%v: unable to resolve extension %v: %v", mi.Desc.FullName(), num, err) diff --git a/vendor/google.golang.org/protobuf/internal/impl/enum.go b/vendor/google.golang.org/protobuf/internal/impl/enum.go index 8c1eab4bf..5f3ef5ad7 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/enum.go +++ b/vendor/google.golang.org/protobuf/internal/impl/enum.go @@ -7,15 +7,15 @@ package impl import ( "reflect" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type EnumInfo struct { GoReflectType reflect.Type // int32 kind - Desc pref.EnumDescriptor + Desc protoreflect.EnumDescriptor } -func (t *EnumInfo) New(n pref.EnumNumber) pref.Enum { - return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(pref.Enum) +func (t *EnumInfo) New(n protoreflect.EnumNumber) protoreflect.Enum { + return reflect.ValueOf(n).Convert(t.GoReflectType).Interface().(protoreflect.Enum) } -func (t *EnumInfo) Descriptor() pref.EnumDescriptor { return t.Desc } +func (t *EnumInfo) Descriptor() protoreflect.EnumDescriptor { return t.Desc } diff --git a/vendor/google.golang.org/protobuf/internal/impl/extension.go b/vendor/google.golang.org/protobuf/internal/impl/extension.go index e904fd993..cb25b0bae 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/extension.go +++ b/vendor/google.golang.org/protobuf/internal/impl/extension.go @@ -9,8 +9,8 @@ import ( "sync" "sync/atomic" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" ) // ExtensionInfo implements ExtensionType. @@ -45,7 +45,7 @@ type ExtensionInfo struct { // since the message may no longer implement the MessageV1 interface. // // Deprecated: Use the ExtendedType method instead. - ExtendedType piface.MessageV1 + ExtendedType protoiface.MessageV1 // ExtensionType is the zero value of the extension type. // @@ -83,31 +83,31 @@ const ( extensionInfoFullInit = 2 ) -func InitExtensionInfo(xi *ExtensionInfo, xd pref.ExtensionDescriptor, goType reflect.Type) { +func InitExtensionInfo(xi *ExtensionInfo, xd protoreflect.ExtensionDescriptor, goType reflect.Type) { xi.goType = goType xi.desc = extensionTypeDescriptor{xd, xi} xi.init = extensionInfoDescInit } -func (xi *ExtensionInfo) New() pref.Value { +func (xi *ExtensionInfo) New() protoreflect.Value { return xi.lazyInit().New() } -func (xi *ExtensionInfo) Zero() pref.Value { +func (xi *ExtensionInfo) Zero() protoreflect.Value { return xi.lazyInit().Zero() } -func (xi *ExtensionInfo) ValueOf(v interface{}) pref.Value { +func (xi *ExtensionInfo) ValueOf(v interface{}) protoreflect.Value { return xi.lazyInit().PBValueOf(reflect.ValueOf(v)) } -func (xi *ExtensionInfo) InterfaceOf(v pref.Value) interface{} { +func (xi *ExtensionInfo) InterfaceOf(v protoreflect.Value) interface{} { return xi.lazyInit().GoValueOf(v).Interface() } -func (xi *ExtensionInfo) IsValidValue(v pref.Value) bool { +func (xi *ExtensionInfo) IsValidValue(v protoreflect.Value) bool { return xi.lazyInit().IsValidPB(v) } func (xi *ExtensionInfo) IsValidInterface(v interface{}) bool { return xi.lazyInit().IsValidGo(reflect.ValueOf(v)) } -func (xi *ExtensionInfo) TypeDescriptor() pref.ExtensionTypeDescriptor { +func (xi *ExtensionInfo) TypeDescriptor() protoreflect.ExtensionTypeDescriptor { if atomic.LoadUint32(&xi.init) < extensionInfoDescInit { xi.lazyInitSlow() } @@ -144,13 +144,13 @@ func (xi *ExtensionInfo) lazyInitSlow() { } type extensionTypeDescriptor struct { - pref.ExtensionDescriptor + protoreflect.ExtensionDescriptor xi *ExtensionInfo } -func (xtd *extensionTypeDescriptor) Type() pref.ExtensionType { +func (xtd *extensionTypeDescriptor) Type() protoreflect.ExtensionType { return xtd.xi } -func (xtd *extensionTypeDescriptor) Descriptor() pref.ExtensionDescriptor { +func (xtd *extensionTypeDescriptor) Descriptor() protoreflect.ExtensionDescriptor { return xtd.ExtensionDescriptor } diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go index f7d7ffb51..c2a803bb2 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go @@ -13,13 +13,12 @@ import ( "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/reflect/protoreflect" - pref "google.golang.org/protobuf/reflect/protoreflect" ) // legacyEnumName returns the name of enums used in legacy code. // It is neither the protobuf full name nor the qualified Go name, // but rather an odd hybrid of both. -func legacyEnumName(ed pref.EnumDescriptor) string { +func legacyEnumName(ed protoreflect.EnumDescriptor) string { var protoPkg string enumName := string(ed.FullName()) if fd := ed.ParentFile(); fd != nil { @@ -34,68 +33,68 @@ func legacyEnumName(ed pref.EnumDescriptor) string { // legacyWrapEnum wraps v as a protoreflect.Enum, // where v must be a int32 kind and not implement the v2 API already. -func legacyWrapEnum(v reflect.Value) pref.Enum { +func legacyWrapEnum(v reflect.Value) protoreflect.Enum { et := legacyLoadEnumType(v.Type()) - return et.New(pref.EnumNumber(v.Int())) + return et.New(protoreflect.EnumNumber(v.Int())) } var legacyEnumTypeCache sync.Map // map[reflect.Type]protoreflect.EnumType // legacyLoadEnumType dynamically loads a protoreflect.EnumType for t, // where t must be an int32 kind and not implement the v2 API already. -func legacyLoadEnumType(t reflect.Type) pref.EnumType { +func legacyLoadEnumType(t reflect.Type) protoreflect.EnumType { // Fast-path: check if a EnumType is cached for this concrete type. if et, ok := legacyEnumTypeCache.Load(t); ok { - return et.(pref.EnumType) + return et.(protoreflect.EnumType) } // Slow-path: derive enum descriptor and initialize EnumType. - var et pref.EnumType + var et protoreflect.EnumType ed := LegacyLoadEnumDesc(t) et = &legacyEnumType{ desc: ed, goType: t, } if et, ok := legacyEnumTypeCache.LoadOrStore(t, et); ok { - return et.(pref.EnumType) + return et.(protoreflect.EnumType) } return et } type legacyEnumType struct { - desc pref.EnumDescriptor + desc protoreflect.EnumDescriptor goType reflect.Type m sync.Map // map[protoreflect.EnumNumber]proto.Enum } -func (t *legacyEnumType) New(n pref.EnumNumber) pref.Enum { +func (t *legacyEnumType) New(n protoreflect.EnumNumber) protoreflect.Enum { if e, ok := t.m.Load(n); ok { - return e.(pref.Enum) + return e.(protoreflect.Enum) } e := &legacyEnumWrapper{num: n, pbTyp: t, goTyp: t.goType} t.m.Store(n, e) return e } -func (t *legacyEnumType) Descriptor() pref.EnumDescriptor { +func (t *legacyEnumType) Descriptor() protoreflect.EnumDescriptor { return t.desc } type legacyEnumWrapper struct { - num pref.EnumNumber - pbTyp pref.EnumType + num protoreflect.EnumNumber + pbTyp protoreflect.EnumType goTyp reflect.Type } -func (e *legacyEnumWrapper) Descriptor() pref.EnumDescriptor { +func (e *legacyEnumWrapper) Descriptor() protoreflect.EnumDescriptor { return e.pbTyp.Descriptor() } -func (e *legacyEnumWrapper) Type() pref.EnumType { +func (e *legacyEnumWrapper) Type() protoreflect.EnumType { return e.pbTyp } -func (e *legacyEnumWrapper) Number() pref.EnumNumber { +func (e *legacyEnumWrapper) Number() protoreflect.EnumNumber { return e.num } -func (e *legacyEnumWrapper) ProtoReflect() pref.Enum { +func (e *legacyEnumWrapper) ProtoReflect() protoreflect.Enum { return e } func (e *legacyEnumWrapper) protoUnwrap() interface{} { @@ -105,8 +104,8 @@ func (e *legacyEnumWrapper) protoUnwrap() interface{} { } var ( - _ pref.Enum = (*legacyEnumWrapper)(nil) - _ unwrapper = (*legacyEnumWrapper)(nil) + _ protoreflect.Enum = (*legacyEnumWrapper)(nil) + _ unwrapper = (*legacyEnumWrapper)(nil) ) var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor @@ -115,15 +114,15 @@ var legacyEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescriptor // which must be an int32 kind and not implement the v2 API already. // // This is exported for testing purposes. -func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { +func LegacyLoadEnumDesc(t reflect.Type) protoreflect.EnumDescriptor { // Fast-path: check if an EnumDescriptor is cached for this concrete type. if ed, ok := legacyEnumDescCache.Load(t); ok { - return ed.(pref.EnumDescriptor) + return ed.(protoreflect.EnumDescriptor) } // Slow-path: initialize EnumDescriptor from the raw descriptor. ev := reflect.Zero(t).Interface() - if _, ok := ev.(pref.Enum); ok { + if _, ok := ev.(protoreflect.Enum); ok { panic(fmt.Sprintf("%v already implements proto.Enum", t)) } edV1, ok := ev.(enumV1) @@ -132,7 +131,7 @@ func LegacyLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { } b, idxs := edV1.EnumDescriptor() - var ed pref.EnumDescriptor + var ed protoreflect.EnumDescriptor if len(idxs) == 1 { ed = legacyLoadFileDesc(b).Enums().Get(idxs[0]) } else { @@ -158,10 +157,10 @@ var aberrantEnumDescCache sync.Map // map[reflect.Type]protoreflect.EnumDescript // We are unable to use the global enum registry since it is // unfortunately keyed by the protobuf full name, which we also do not know. // Thus, this produces some bogus enum descriptor based on the Go type name. -func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { +func aberrantLoadEnumDesc(t reflect.Type) protoreflect.EnumDescriptor { // Fast-path: check if an EnumDescriptor is cached for this concrete type. if ed, ok := aberrantEnumDescCache.Load(t); ok { - return ed.(pref.EnumDescriptor) + return ed.(protoreflect.EnumDescriptor) } // Slow-path: construct a bogus, but unique EnumDescriptor. @@ -182,7 +181,7 @@ func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { // An exhaustive query is clearly impractical, but can be best-effort. if ed, ok := aberrantEnumDescCache.LoadOrStore(t, ed); ok { - return ed.(pref.EnumDescriptor) + return ed.(protoreflect.EnumDescriptor) } return ed } @@ -192,7 +191,7 @@ func aberrantLoadEnumDesc(t reflect.Type) pref.EnumDescriptor { // It should be sufficiently unique within a program. // // This is exported for testing purposes. -func AberrantDeriveFullName(t reflect.Type) pref.FullName { +func AberrantDeriveFullName(t reflect.Type) protoreflect.FullName { sanitize := func(r rune) rune { switch { case r == '/': @@ -215,5 +214,5 @@ func AberrantDeriveFullName(t reflect.Type) pref.FullName { ss[i] = "x" + s } } - return pref.FullName(strings.Join(ss, ".")) + return protoreflect.FullName(strings.Join(ss, ".")) } diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go index e3fb0b578..9b64ad5bb 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_export.go @@ -12,21 +12,21 @@ import ( "reflect" "google.golang.org/protobuf/internal/errors" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" ) // These functions exist to support exported APIs in generated protobufs. // While these are deprecated, they cannot be removed for compatibility reasons. // LegacyEnumName returns the name of enums used in legacy code. -func (Export) LegacyEnumName(ed pref.EnumDescriptor) string { +func (Export) LegacyEnumName(ed protoreflect.EnumDescriptor) string { return legacyEnumName(ed) } // LegacyMessageTypeOf returns the protoreflect.MessageType for m, // with name used as the message name if necessary. -func (Export) LegacyMessageTypeOf(m piface.MessageV1, name pref.FullName) pref.MessageType { +func (Export) LegacyMessageTypeOf(m protoiface.MessageV1, name protoreflect.FullName) protoreflect.MessageType { if mv := (Export{}).protoMessageV2Of(m); mv != nil { return mv.ProtoReflect().Type() } @@ -36,9 +36,9 @@ func (Export) LegacyMessageTypeOf(m piface.MessageV1, name pref.FullName) pref.M // UnmarshalJSONEnum unmarshals an enum from a JSON-encoded input. // The input can either be a string representing the enum value by name, // or a number representing the enum number itself. -func (Export) UnmarshalJSONEnum(ed pref.EnumDescriptor, b []byte) (pref.EnumNumber, error) { +func (Export) UnmarshalJSONEnum(ed protoreflect.EnumDescriptor, b []byte) (protoreflect.EnumNumber, error) { if b[0] == '"' { - var name pref.Name + var name protoreflect.Name if err := json.Unmarshal(b, &name); err != nil { return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b) } @@ -48,7 +48,7 @@ func (Export) UnmarshalJSONEnum(ed pref.EnumDescriptor, b []byte) (pref.EnumNumb } return ev.Number(), nil } else { - var num pref.EnumNumber + var num protoreflect.EnumNumber if err := json.Unmarshal(b, &num); err != nil { return 0, errors.New("invalid input for enum %v: %s", ed.FullName(), b) } @@ -81,8 +81,8 @@ func (Export) CompressGZIP(in []byte) (out []byte) { blockHeader[0] = 0x01 // final bit per RFC 1951, section 3.2.3. blockSize = len(in) } - binary.LittleEndian.PutUint16(blockHeader[1:3], uint16(blockSize)^0x0000) - binary.LittleEndian.PutUint16(blockHeader[3:5], uint16(blockSize)^0xffff) + binary.LittleEndian.PutUint16(blockHeader[1:3], uint16(blockSize)) + binary.LittleEndian.PutUint16(blockHeader[3:5], ^uint16(blockSize)) out = append(out, blockHeader[:]...) out = append(out, in[:blockSize]...) in = in[blockSize:] diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go index 49e723161..87b30d050 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go @@ -12,16 +12,16 @@ import ( ptag "google.golang.org/protobuf/internal/encoding/tag" "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/pragma" - pref "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoiface" ) func (xi *ExtensionInfo) initToLegacy() { xd := xi.desc - var parent piface.MessageV1 + var parent protoiface.MessageV1 messageName := xd.ContainingMessage().FullName() - if mt, _ := preg.GlobalTypes.FindMessageByName(messageName); mt != nil { + if mt, _ := protoregistry.GlobalTypes.FindMessageByName(messageName); mt != nil { // Create a new parent message and unwrap it if possible. mv := mt.New().Interface() t := reflect.TypeOf(mv) @@ -31,7 +31,7 @@ func (xi *ExtensionInfo) initToLegacy() { // Check whether the message implements the legacy v1 Message interface. mz := reflect.Zero(t).Interface() - if mz, ok := mz.(piface.MessageV1); ok { + if mz, ok := mz.(protoiface.MessageV1); ok { parent = mz } } @@ -46,7 +46,7 @@ func (xi *ExtensionInfo) initToLegacy() { // Reconstruct the legacy enum full name. var enumName string - if xd.Kind() == pref.EnumKind { + if xd.Kind() == protoreflect.EnumKind { enumName = legacyEnumName(xd.Enum()) } @@ -77,16 +77,16 @@ func (xi *ExtensionInfo) initFromLegacy() { // field number is specified. In such a case, use a placeholder. if xi.ExtendedType == nil || xi.ExtensionType == nil { xd := placeholderExtension{ - name: pref.FullName(xi.Name), - number: pref.FieldNumber(xi.Field), + name: protoreflect.FullName(xi.Name), + number: protoreflect.FieldNumber(xi.Field), } xi.desc = extensionTypeDescriptor{xd, xi} return } // Resolve enum or message dependencies. - var ed pref.EnumDescriptor - var md pref.MessageDescriptor + var ed protoreflect.EnumDescriptor + var md protoreflect.MessageDescriptor t := reflect.TypeOf(xi.ExtensionType) isOptional := t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct isRepeated := t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 @@ -94,18 +94,18 @@ func (xi *ExtensionInfo) initFromLegacy() { t = t.Elem() } switch v := reflect.Zero(t).Interface().(type) { - case pref.Enum: + case protoreflect.Enum: ed = v.Descriptor() case enumV1: ed = LegacyLoadEnumDesc(t) - case pref.ProtoMessage: + case protoreflect.ProtoMessage: md = v.ProtoReflect().Descriptor() case messageV1: md = LegacyLoadMessageDesc(t) } // Derive basic field information from the struct tag. - var evs pref.EnumValueDescriptors + var evs protoreflect.EnumValueDescriptors if ed != nil { evs = ed.Values() } @@ -114,8 +114,8 @@ func (xi *ExtensionInfo) initFromLegacy() { // Construct a v2 ExtensionType. xd := &filedesc.Extension{L2: new(filedesc.ExtensionL2)} xd.L0.ParentFile = filedesc.SurrogateProto2 - xd.L0.FullName = pref.FullName(xi.Name) - xd.L1.Number = pref.FieldNumber(xi.Field) + xd.L0.FullName = protoreflect.FullName(xi.Name) + xd.L1.Number = protoreflect.FieldNumber(xi.Field) xd.L1.Cardinality = fd.L1.Cardinality xd.L1.Kind = fd.L1.Kind xd.L2.IsPacked = fd.L1.IsPacked @@ -138,39 +138,39 @@ func (xi *ExtensionInfo) initFromLegacy() { } type placeholderExtension struct { - name pref.FullName - number pref.FieldNumber + name protoreflect.FullName + number protoreflect.FieldNumber } -func (x placeholderExtension) ParentFile() pref.FileDescriptor { return nil } -func (x placeholderExtension) Parent() pref.Descriptor { return nil } -func (x placeholderExtension) Index() int { return 0 } -func (x placeholderExtension) Syntax() pref.Syntax { return 0 } -func (x placeholderExtension) Name() pref.Name { return x.name.Name() } -func (x placeholderExtension) FullName() pref.FullName { return x.name } -func (x placeholderExtension) IsPlaceholder() bool { return true } -func (x placeholderExtension) Options() pref.ProtoMessage { return descopts.Field } -func (x placeholderExtension) Number() pref.FieldNumber { return x.number } -func (x placeholderExtension) Cardinality() pref.Cardinality { return 0 } -func (x placeholderExtension) Kind() pref.Kind { return 0 } -func (x placeholderExtension) HasJSONName() bool { return false } -func (x placeholderExtension) JSONName() string { return "[" + string(x.name) + "]" } -func (x placeholderExtension) TextName() string { return "[" + string(x.name) + "]" } -func (x placeholderExtension) HasPresence() bool { return false } -func (x placeholderExtension) HasOptionalKeyword() bool { return false } -func (x placeholderExtension) IsExtension() bool { return true } -func (x placeholderExtension) IsWeak() bool { return false } -func (x placeholderExtension) IsPacked() bool { return false } -func (x placeholderExtension) IsList() bool { return false } -func (x placeholderExtension) IsMap() bool { return false } -func (x placeholderExtension) MapKey() pref.FieldDescriptor { return nil } -func (x placeholderExtension) MapValue() pref.FieldDescriptor { return nil } -func (x placeholderExtension) HasDefault() bool { return false } -func (x placeholderExtension) Default() pref.Value { return pref.Value{} } -func (x placeholderExtension) DefaultEnumValue() pref.EnumValueDescriptor { return nil } -func (x placeholderExtension) ContainingOneof() pref.OneofDescriptor { return nil } -func (x placeholderExtension) ContainingMessage() pref.MessageDescriptor { return nil } -func (x placeholderExtension) Enum() pref.EnumDescriptor { return nil } -func (x placeholderExtension) Message() pref.MessageDescriptor { return nil } -func (x placeholderExtension) ProtoType(pref.FieldDescriptor) { return } -func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement) { return } +func (x placeholderExtension) ParentFile() protoreflect.FileDescriptor { return nil } +func (x placeholderExtension) Parent() protoreflect.Descriptor { return nil } +func (x placeholderExtension) Index() int { return 0 } +func (x placeholderExtension) Syntax() protoreflect.Syntax { return 0 } +func (x placeholderExtension) Name() protoreflect.Name { return x.name.Name() } +func (x placeholderExtension) FullName() protoreflect.FullName { return x.name } +func (x placeholderExtension) IsPlaceholder() bool { return true } +func (x placeholderExtension) Options() protoreflect.ProtoMessage { return descopts.Field } +func (x placeholderExtension) Number() protoreflect.FieldNumber { return x.number } +func (x placeholderExtension) Cardinality() protoreflect.Cardinality { return 0 } +func (x placeholderExtension) Kind() protoreflect.Kind { return 0 } +func (x placeholderExtension) HasJSONName() bool { return false } +func (x placeholderExtension) JSONName() string { return "[" + string(x.name) + "]" } +func (x placeholderExtension) TextName() string { return "[" + string(x.name) + "]" } +func (x placeholderExtension) HasPresence() bool { return false } +func (x placeholderExtension) HasOptionalKeyword() bool { return false } +func (x placeholderExtension) IsExtension() bool { return true } +func (x placeholderExtension) IsWeak() bool { return false } +func (x placeholderExtension) IsPacked() bool { return false } +func (x placeholderExtension) IsList() bool { return false } +func (x placeholderExtension) IsMap() bool { return false } +func (x placeholderExtension) MapKey() protoreflect.FieldDescriptor { return nil } +func (x placeholderExtension) MapValue() protoreflect.FieldDescriptor { return nil } +func (x placeholderExtension) HasDefault() bool { return false } +func (x placeholderExtension) Default() protoreflect.Value { return protoreflect.Value{} } +func (x placeholderExtension) DefaultEnumValue() protoreflect.EnumValueDescriptor { return nil } +func (x placeholderExtension) ContainingOneof() protoreflect.OneofDescriptor { return nil } +func (x placeholderExtension) ContainingMessage() protoreflect.MessageDescriptor { return nil } +func (x placeholderExtension) Enum() protoreflect.EnumDescriptor { return nil } +func (x placeholderExtension) Message() protoreflect.MessageDescriptor { return nil } +func (x placeholderExtension) ProtoType(protoreflect.FieldDescriptor) { return } +func (x placeholderExtension) ProtoInternal(pragma.DoNotImplement) { return } diff --git a/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go index 029feeefd..61c483fac 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go +++ b/vendor/google.golang.org/protobuf/internal/impl/legacy_message.go @@ -16,14 +16,12 @@ import ( "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/reflect/protoreflect" - pref "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/runtime/protoiface" - piface "google.golang.org/protobuf/runtime/protoiface" ) // legacyWrapMessage wraps v as a protoreflect.Message, // where v must be a *struct kind and not implement the v2 API already. -func legacyWrapMessage(v reflect.Value) pref.Message { +func legacyWrapMessage(v reflect.Value) protoreflect.Message { t := v.Type() if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct { return aberrantMessage{v: v} @@ -35,7 +33,7 @@ func legacyWrapMessage(v reflect.Value) pref.Message { // legacyLoadMessageType dynamically loads a protoreflect.Type for t, // where t must be not implement the v2 API already. // The provided name is used if it cannot be determined from the message. -func legacyLoadMessageType(t reflect.Type, name pref.FullName) protoreflect.MessageType { +func legacyLoadMessageType(t reflect.Type, name protoreflect.FullName) protoreflect.MessageType { if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct { return aberrantMessageType{t} } @@ -47,7 +45,7 @@ var legacyMessageTypeCache sync.Map // map[reflect.Type]*MessageInfo // legacyLoadMessageInfo dynamically loads a *MessageInfo for t, // where t must be a *struct kind and not implement the v2 API already. // The provided name is used if it cannot be determined from the message. -func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo { +func legacyLoadMessageInfo(t reflect.Type, name protoreflect.FullName) *MessageInfo { // Fast-path: check if a MessageInfo is cached for this concrete type. if mt, ok := legacyMessageTypeCache.Load(t); ok { return mt.(*MessageInfo) @@ -68,7 +66,7 @@ func legacyLoadMessageInfo(t reflect.Type, name pref.FullName) *MessageInfo { // supports deterministic serialization or not, but this // preserves the v1 implementation's behavior of always // calling Marshal methods when present. - mi.methods.Flags |= piface.SupportMarshalDeterministic + mi.methods.Flags |= protoiface.SupportMarshalDeterministic } if _, hasUnmarshal = v.(legacyUnmarshaler); hasUnmarshal { mi.methods.Unmarshal = legacyUnmarshal @@ -89,18 +87,18 @@ var legacyMessageDescCache sync.Map // map[reflect.Type]protoreflect.MessageDesc // which should be a *struct kind and must not implement the v2 API already. // // This is exported for testing purposes. -func LegacyLoadMessageDesc(t reflect.Type) pref.MessageDescriptor { +func LegacyLoadMessageDesc(t reflect.Type) protoreflect.MessageDescriptor { return legacyLoadMessageDesc(t, "") } -func legacyLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor { +func legacyLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor { // Fast-path: check if a MessageDescriptor is cached for this concrete type. if mi, ok := legacyMessageDescCache.Load(t); ok { - return mi.(pref.MessageDescriptor) + return mi.(protoreflect.MessageDescriptor) } // Slow-path: initialize MessageDescriptor from the raw descriptor. mv := reflect.Zero(t).Interface() - if _, ok := mv.(pref.ProtoMessage); ok { + if _, ok := mv.(protoreflect.ProtoMessage); ok { panic(fmt.Sprintf("%v already implements proto.Message", t)) } mdV1, ok := mv.(messageV1) @@ -164,7 +162,7 @@ var ( // // This is a best-effort derivation of the message descriptor using the protobuf // tags on the struct fields. -func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDescriptor { +func aberrantLoadMessageDesc(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor { aberrantMessageDescLock.Lock() defer aberrantMessageDescLock.Unlock() if aberrantMessageDescCache == nil { @@ -172,7 +170,7 @@ func aberrantLoadMessageDesc(t reflect.Type, name pref.FullName) pref.MessageDes } return aberrantLoadMessageDescReentrant(t, name) } -func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.MessageDescriptor { +func aberrantLoadMessageDescReentrant(t reflect.Type, name protoreflect.FullName) protoreflect.MessageDescriptor { // Fast-path: check if an MessageDescriptor is cached for this concrete type. if md, ok := aberrantMessageDescCache[t]; ok { return md @@ -225,9 +223,9 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.M vs := fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0] for i := 0; i < vs.Len(); i++ { v := vs.Index(i) - md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]pref.FieldNumber{ - pref.FieldNumber(v.FieldByName("Start").Int()), - pref.FieldNumber(v.FieldByName("End").Int() + 1), + md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, [2]protoreflect.FieldNumber{ + protoreflect.FieldNumber(v.FieldByName("Start").Int()), + protoreflect.FieldNumber(v.FieldByName("End").Int() + 1), }) md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, nil) } @@ -245,7 +243,7 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.M n := len(md.L2.Oneofs.List) md.L2.Oneofs.List = append(md.L2.Oneofs.List, filedesc.Oneof{}) od := &md.L2.Oneofs.List[n] - od.L0.FullName = md.FullName().Append(pref.Name(tag)) + od.L0.FullName = md.FullName().Append(protoreflect.Name(tag)) od.L0.ParentFile = md.L0.ParentFile od.L0.Parent = md od.L0.Index = n @@ -267,14 +265,14 @@ func aberrantLoadMessageDescReentrant(t reflect.Type, name pref.FullName) pref.M return md } -func aberrantDeriveMessageName(t reflect.Type, name pref.FullName) pref.FullName { +func aberrantDeriveMessageName(t reflect.Type, name protoreflect.FullName) protoreflect.FullName { if name.IsValid() { return name } func() { defer func() { recover() }() // swallow possible nil panics if m, ok := reflect.Zero(t).Interface().(interface{ XXX_MessageName() string }); ok { - name = pref.FullName(m.XXX_MessageName()) + name = protoreflect.FullName(m.XXX_MessageName()) } }() if name.IsValid() { @@ -305,7 +303,7 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, fd.L0.Index = n if fd.L1.IsWeak || fd.L1.HasPacked { - fd.L1.Options = func() pref.ProtoMessage { + fd.L1.Options = func() protoreflect.ProtoMessage { opts := descopts.Field.ProtoReflect().New() if fd.L1.IsWeak { opts.Set(opts.Descriptor().Fields().ByName("weak"), protoreflect.ValueOfBool(true)) @@ -318,17 +316,17 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, } // Populate Enum and Message. - if fd.Enum() == nil && fd.Kind() == pref.EnumKind { + if fd.Enum() == nil && fd.Kind() == protoreflect.EnumKind { switch v := reflect.Zero(t).Interface().(type) { - case pref.Enum: + case protoreflect.Enum: fd.L1.Enum = v.Descriptor() default: fd.L1.Enum = LegacyLoadEnumDesc(t) } } - if fd.Message() == nil && (fd.Kind() == pref.MessageKind || fd.Kind() == pref.GroupKind) { + if fd.Message() == nil && (fd.Kind() == protoreflect.MessageKind || fd.Kind() == protoreflect.GroupKind) { switch v := reflect.Zero(t).Interface().(type) { - case pref.ProtoMessage: + case protoreflect.ProtoMessage: fd.L1.Message = v.ProtoReflect().Descriptor() case messageV1: fd.L1.Message = LegacyLoadMessageDesc(t) @@ -337,13 +335,13 @@ func aberrantAppendField(md *filedesc.Message, goType reflect.Type, tag, tagKey, n := len(md.L1.Messages.List) md.L1.Messages.List = append(md.L1.Messages.List, filedesc.Message{L2: new(filedesc.MessageL2)}) md2 := &md.L1.Messages.List[n] - md2.L0.FullName = md.FullName().Append(pref.Name(strs.MapEntryName(string(fd.Name())))) + md2.L0.FullName = md.FullName().Append(protoreflect.Name(strs.MapEntryName(string(fd.Name())))) md2.L0.ParentFile = md.L0.ParentFile md2.L0.Parent = md md2.L0.Index = n md2.L1.IsMapEntry = true - md2.L2.Options = func() pref.ProtoMessage { + md2.L2.Options = func() protoreflect.ProtoMessage { opts := descopts.Message.ProtoReflect().New() opts.Set(opts.Descriptor().Fields().ByName("map_entry"), protoreflect.ValueOfBool(true)) return opts.Interface() @@ -364,8 +362,8 @@ type placeholderEnumValues struct { protoreflect.EnumValueDescriptors } -func (placeholderEnumValues) ByNumber(n pref.EnumNumber) pref.EnumValueDescriptor { - return filedesc.PlaceholderEnumValue(pref.FullName(fmt.Sprintf("UNKNOWN_%d", n))) +func (placeholderEnumValues) ByNumber(n protoreflect.EnumNumber) protoreflect.EnumValueDescriptor { + return filedesc.PlaceholderEnumValue(protoreflect.FullName(fmt.Sprintf("UNKNOWN_%d", n))) } // legacyMarshaler is the proto.Marshaler interface superseded by protoiface.Methoder. @@ -383,7 +381,7 @@ type legacyMerger interface { Merge(protoiface.MessageV1) } -var aberrantProtoMethods = &piface.Methods{ +var aberrantProtoMethods = &protoiface.Methods{ Marshal: legacyMarshal, Unmarshal: legacyUnmarshal, Merge: legacyMerge, @@ -392,40 +390,40 @@ var aberrantProtoMethods = &piface.Methods{ // supports deterministic serialization or not, but this // preserves the v1 implementation's behavior of always // calling Marshal methods when present. - Flags: piface.SupportMarshalDeterministic, + Flags: protoiface.SupportMarshalDeterministic, } -func legacyMarshal(in piface.MarshalInput) (piface.MarshalOutput, error) { +func legacyMarshal(in protoiface.MarshalInput) (protoiface.MarshalOutput, error) { v := in.Message.(unwrapper).protoUnwrap() marshaler, ok := v.(legacyMarshaler) if !ok { - return piface.MarshalOutput{}, errors.New("%T does not implement Marshal", v) + return protoiface.MarshalOutput{}, errors.New("%T does not implement Marshal", v) } out, err := marshaler.Marshal() if in.Buf != nil { out = append(in.Buf, out...) } - return piface.MarshalOutput{ + return protoiface.MarshalOutput{ Buf: out, }, err } -func legacyUnmarshal(in piface.UnmarshalInput) (piface.UnmarshalOutput, error) { +func legacyUnmarshal(in protoiface.UnmarshalInput) (protoiface.UnmarshalOutput, error) { v := in.Message.(unwrapper).protoUnwrap() unmarshaler, ok := v.(legacyUnmarshaler) if !ok { - return piface.UnmarshalOutput{}, errors.New("%T does not implement Unmarshal", v) + return protoiface.UnmarshalOutput{}, errors.New("%T does not implement Unmarshal", v) } - return piface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf) + return protoiface.UnmarshalOutput{}, unmarshaler.Unmarshal(in.Buf) } -func legacyMerge(in piface.MergeInput) piface.MergeOutput { +func legacyMerge(in protoiface.MergeInput) protoiface.MergeOutput { // Check whether this supports the legacy merger. dstv := in.Destination.(unwrapper).protoUnwrap() merger, ok := dstv.(legacyMerger) if ok { merger.Merge(Export{}.ProtoMessageV1Of(in.Source)) - return piface.MergeOutput{Flags: piface.MergeComplete} + return protoiface.MergeOutput{Flags: protoiface.MergeComplete} } // If legacy merger is unavailable, implement merge in terms of @@ -433,29 +431,29 @@ func legacyMerge(in piface.MergeInput) piface.MergeOutput { srcv := in.Source.(unwrapper).protoUnwrap() marshaler, ok := srcv.(legacyMarshaler) if !ok { - return piface.MergeOutput{} + return protoiface.MergeOutput{} } dstv = in.Destination.(unwrapper).protoUnwrap() unmarshaler, ok := dstv.(legacyUnmarshaler) if !ok { - return piface.MergeOutput{} + return protoiface.MergeOutput{} } if !in.Source.IsValid() { // Legacy Marshal methods may not function on nil messages. // Check for a typed nil source only after we confirm that // legacy Marshal/Unmarshal methods are present, for // consistency. - return piface.MergeOutput{Flags: piface.MergeComplete} + return protoiface.MergeOutput{Flags: protoiface.MergeComplete} } b, err := marshaler.Marshal() if err != nil { - return piface.MergeOutput{} + return protoiface.MergeOutput{} } err = unmarshaler.Unmarshal(b) if err != nil { - return piface.MergeOutput{} + return protoiface.MergeOutput{} } - return piface.MergeOutput{Flags: piface.MergeComplete} + return protoiface.MergeOutput{Flags: protoiface.MergeComplete} } // aberrantMessageType implements MessageType for all types other than pointer-to-struct. @@ -463,19 +461,19 @@ type aberrantMessageType struct { t reflect.Type } -func (mt aberrantMessageType) New() pref.Message { +func (mt aberrantMessageType) New() protoreflect.Message { if mt.t.Kind() == reflect.Ptr { return aberrantMessage{reflect.New(mt.t.Elem())} } return aberrantMessage{reflect.Zero(mt.t)} } -func (mt aberrantMessageType) Zero() pref.Message { +func (mt aberrantMessageType) Zero() protoreflect.Message { return aberrantMessage{reflect.Zero(mt.t)} } func (mt aberrantMessageType) GoType() reflect.Type { return mt.t } -func (mt aberrantMessageType) Descriptor() pref.MessageDescriptor { +func (mt aberrantMessageType) Descriptor() protoreflect.MessageDescriptor { return LegacyLoadMessageDesc(mt.t) } @@ -499,56 +497,56 @@ func (m aberrantMessage) Reset() { } } -func (m aberrantMessage) ProtoReflect() pref.Message { +func (m aberrantMessage) ProtoReflect() protoreflect.Message { return m } -func (m aberrantMessage) Descriptor() pref.MessageDescriptor { +func (m aberrantMessage) Descriptor() protoreflect.MessageDescriptor { return LegacyLoadMessageDesc(m.v.Type()) } -func (m aberrantMessage) Type() pref.MessageType { +func (m aberrantMessage) Type() protoreflect.MessageType { return aberrantMessageType{m.v.Type()} } -func (m aberrantMessage) New() pref.Message { +func (m aberrantMessage) New() protoreflect.Message { if m.v.Type().Kind() == reflect.Ptr { return aberrantMessage{reflect.New(m.v.Type().Elem())} } return aberrantMessage{reflect.Zero(m.v.Type())} } -func (m aberrantMessage) Interface() pref.ProtoMessage { +func (m aberrantMessage) Interface() protoreflect.ProtoMessage { return m } -func (m aberrantMessage) Range(f func(pref.FieldDescriptor, pref.Value) bool) { +func (m aberrantMessage) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { return } -func (m aberrantMessage) Has(pref.FieldDescriptor) bool { +func (m aberrantMessage) Has(protoreflect.FieldDescriptor) bool { return false } -func (m aberrantMessage) Clear(pref.FieldDescriptor) { +func (m aberrantMessage) Clear(protoreflect.FieldDescriptor) { panic("invalid Message.Clear on " + string(m.Descriptor().FullName())) } -func (m aberrantMessage) Get(fd pref.FieldDescriptor) pref.Value { +func (m aberrantMessage) Get(fd protoreflect.FieldDescriptor) protoreflect.Value { if fd.Default().IsValid() { return fd.Default() } panic("invalid Message.Get on " + string(m.Descriptor().FullName())) } -func (m aberrantMessage) Set(pref.FieldDescriptor, pref.Value) { +func (m aberrantMessage) Set(protoreflect.FieldDescriptor, protoreflect.Value) { panic("invalid Message.Set on " + string(m.Descriptor().FullName())) } -func (m aberrantMessage) Mutable(pref.FieldDescriptor) pref.Value { +func (m aberrantMessage) Mutable(protoreflect.FieldDescriptor) protoreflect.Value { panic("invalid Message.Mutable on " + string(m.Descriptor().FullName())) } -func (m aberrantMessage) NewField(pref.FieldDescriptor) pref.Value { +func (m aberrantMessage) NewField(protoreflect.FieldDescriptor) protoreflect.Value { panic("invalid Message.NewField on " + string(m.Descriptor().FullName())) } -func (m aberrantMessage) WhichOneof(pref.OneofDescriptor) pref.FieldDescriptor { +func (m aberrantMessage) WhichOneof(protoreflect.OneofDescriptor) protoreflect.FieldDescriptor { panic("invalid Message.WhichOneof descriptor on " + string(m.Descriptor().FullName())) } -func (m aberrantMessage) GetUnknown() pref.RawFields { +func (m aberrantMessage) GetUnknown() protoreflect.RawFields { return nil } -func (m aberrantMessage) SetUnknown(pref.RawFields) { +func (m aberrantMessage) SetUnknown(protoreflect.RawFields) { // SetUnknown discards its input on messages which don't support unknown field storage. } func (m aberrantMessage) IsValid() bool { @@ -557,7 +555,7 @@ func (m aberrantMessage) IsValid() bool { } return false } -func (m aberrantMessage) ProtoMethods() *piface.Methods { +func (m aberrantMessage) ProtoMethods() *protoiface.Methods { return aberrantProtoMethods } func (m aberrantMessage) protoUnwrap() interface{} { diff --git a/vendor/google.golang.org/protobuf/internal/impl/merge.go b/vendor/google.golang.org/protobuf/internal/impl/merge.go index c65bbc044..7e65f64f2 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/merge.go +++ b/vendor/google.golang.org/protobuf/internal/impl/merge.go @@ -9,8 +9,8 @@ import ( "reflect" "google.golang.org/protobuf/proto" - pref "google.golang.org/protobuf/reflect/protoreflect" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" ) type mergeOptions struct{} @@ -20,17 +20,17 @@ func (o mergeOptions) Merge(dst, src proto.Message) { } // merge is protoreflect.Methods.Merge. -func (mi *MessageInfo) merge(in piface.MergeInput) piface.MergeOutput { +func (mi *MessageInfo) merge(in protoiface.MergeInput) protoiface.MergeOutput { dp, ok := mi.getPointer(in.Destination) if !ok { - return piface.MergeOutput{} + return protoiface.MergeOutput{} } sp, ok := mi.getPointer(in.Source) if !ok { - return piface.MergeOutput{} + return protoiface.MergeOutput{} } mi.mergePointer(dp, sp, mergeOptions{}) - return piface.MergeOutput{Flags: piface.MergeComplete} + return protoiface.MergeOutput{Flags: protoiface.MergeComplete} } func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) { @@ -64,7 +64,7 @@ func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) { continue } dx := (*dext)[num] - var dv pref.Value + var dv protoreflect.Value if dx.Type() == sx.Type() { dv = dx.Value() } @@ -85,15 +85,15 @@ func (mi *MessageInfo) mergePointer(dst, src pointer, opts mergeOptions) { } } -func mergeScalarValue(dst, src pref.Value, opts mergeOptions) pref.Value { +func mergeScalarValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value { return src } -func mergeBytesValue(dst, src pref.Value, opts mergeOptions) pref.Value { - return pref.ValueOfBytes(append(emptyBuf[:], src.Bytes()...)) +func mergeBytesValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value { + return protoreflect.ValueOfBytes(append(emptyBuf[:], src.Bytes()...)) } -func mergeListValue(dst, src pref.Value, opts mergeOptions) pref.Value { +func mergeListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value { dstl := dst.List() srcl := src.List() for i, llen := 0, srcl.Len(); i < llen; i++ { @@ -102,29 +102,29 @@ func mergeListValue(dst, src pref.Value, opts mergeOptions) pref.Value { return dst } -func mergeBytesListValue(dst, src pref.Value, opts mergeOptions) pref.Value { +func mergeBytesListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value { dstl := dst.List() srcl := src.List() for i, llen := 0, srcl.Len(); i < llen; i++ { sb := srcl.Get(i).Bytes() db := append(emptyBuf[:], sb...) - dstl.Append(pref.ValueOfBytes(db)) + dstl.Append(protoreflect.ValueOfBytes(db)) } return dst } -func mergeMessageListValue(dst, src pref.Value, opts mergeOptions) pref.Value { +func mergeMessageListValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value { dstl := dst.List() srcl := src.List() for i, llen := 0, srcl.Len(); i < llen; i++ { sm := srcl.Get(i).Message() dm := proto.Clone(sm.Interface()).ProtoReflect() - dstl.Append(pref.ValueOfMessage(dm)) + dstl.Append(protoreflect.ValueOfMessage(dm)) } return dst } -func mergeMessageValue(dst, src pref.Value, opts mergeOptions) pref.Value { +func mergeMessageValue(dst, src protoreflect.Value, opts mergeOptions) protoreflect.Value { opts.Merge(dst.Message().Interface(), src.Message().Interface()) return dst } diff --git a/vendor/google.golang.org/protobuf/internal/impl/message.go b/vendor/google.golang.org/protobuf/internal/impl/message.go index a104e28e8..4f5fb67a0 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message.go @@ -14,8 +14,7 @@ import ( "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/reflect/protoreflect" - pref "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/reflect/protoregistry" ) // MessageInfo provides protobuf related functionality for a given Go type @@ -29,7 +28,7 @@ type MessageInfo struct { GoReflectType reflect.Type // pointer to struct // Desc is the underlying message descriptor type and must be populated. - Desc pref.MessageDescriptor + Desc protoreflect.MessageDescriptor // Exporter must be provided in a purego environment in order to provide // access to unexported fields. @@ -54,7 +53,7 @@ type exporter func(v interface{}, i int) interface{} // is generated by our implementation of protoc-gen-go (for v2 and on). // If it is unable to obtain a MessageInfo, it returns nil. func getMessageInfo(mt reflect.Type) *MessageInfo { - m, ok := reflect.Zero(mt).Interface().(pref.ProtoMessage) + m, ok := reflect.Zero(mt).Interface().(protoreflect.ProtoMessage) if !ok { return nil } @@ -97,7 +96,7 @@ func (mi *MessageInfo) initOnce() { // getPointer returns the pointer for a message, which should be of // the type of the MessageInfo. If the message is of a different type, // it returns ok==false. -func (mi *MessageInfo) getPointer(m pref.Message) (p pointer, ok bool) { +func (mi *MessageInfo) getPointer(m protoreflect.Message) (p pointer, ok bool) { switch m := m.(type) { case *messageState: return m.pointer(), m.messageInfo() == mi @@ -134,10 +133,10 @@ type structInfo struct { extensionOffset offset extensionType reflect.Type - fieldsByNumber map[pref.FieldNumber]reflect.StructField - oneofsByName map[pref.Name]reflect.StructField - oneofWrappersByType map[reflect.Type]pref.FieldNumber - oneofWrappersByNumber map[pref.FieldNumber]reflect.Type + fieldsByNumber map[protoreflect.FieldNumber]reflect.StructField + oneofsByName map[protoreflect.Name]reflect.StructField + oneofWrappersByType map[reflect.Type]protoreflect.FieldNumber + oneofWrappersByNumber map[protoreflect.FieldNumber]reflect.Type } func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo { @@ -147,10 +146,10 @@ func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo { unknownOffset: invalidOffset, extensionOffset: invalidOffset, - fieldsByNumber: map[pref.FieldNumber]reflect.StructField{}, - oneofsByName: map[pref.Name]reflect.StructField{}, - oneofWrappersByType: map[reflect.Type]pref.FieldNumber{}, - oneofWrappersByNumber: map[pref.FieldNumber]reflect.Type{}, + fieldsByNumber: map[protoreflect.FieldNumber]reflect.StructField{}, + oneofsByName: map[protoreflect.Name]reflect.StructField{}, + oneofWrappersByType: map[reflect.Type]protoreflect.FieldNumber{}, + oneofWrappersByNumber: map[protoreflect.FieldNumber]reflect.Type{}, } fieldLoop: @@ -180,12 +179,12 @@ fieldLoop: for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") { if len(s) > 0 && strings.Trim(s, "0123456789") == "" { n, _ := strconv.ParseUint(s, 10, 64) - si.fieldsByNumber[pref.FieldNumber(n)] = f + si.fieldsByNumber[protoreflect.FieldNumber(n)] = f continue fieldLoop } } if s := f.Tag.Get("protobuf_oneof"); len(s) > 0 { - si.oneofsByName[pref.Name(s)] = f + si.oneofsByName[protoreflect.Name(s)] = f continue fieldLoop } } @@ -208,8 +207,8 @@ fieldLoop: for _, s := range strings.Split(f.Tag.Get("protobuf"), ",") { if len(s) > 0 && strings.Trim(s, "0123456789") == "" { n, _ := strconv.ParseUint(s, 10, 64) - si.oneofWrappersByType[tf] = pref.FieldNumber(n) - si.oneofWrappersByNumber[pref.FieldNumber(n)] = tf + si.oneofWrappersByType[tf] = protoreflect.FieldNumber(n) + si.oneofWrappersByNumber[protoreflect.FieldNumber(n)] = tf break } } @@ -219,7 +218,11 @@ fieldLoop: } func (mi *MessageInfo) New() protoreflect.Message { - return mi.MessageOf(reflect.New(mi.GoReflectType.Elem()).Interface()) + m := reflect.New(mi.GoReflectType.Elem()).Interface() + if r, ok := m.(protoreflect.ProtoMessage); ok { + return r.ProtoReflect() + } + return mi.MessageOf(m) } func (mi *MessageInfo) Zero() protoreflect.Message { return mi.MessageOf(reflect.Zero(mi.GoReflectType).Interface()) @@ -237,7 +240,7 @@ func (mi *MessageInfo) Message(i int) protoreflect.MessageType { fd := mi.Desc.Fields().Get(i) switch { case fd.IsWeak(): - mt, _ := preg.GlobalTypes.FindMessageByName(fd.Message().FullName()) + mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()) return mt case fd.IsMap(): return mapEntryType{fd.Message(), mi.fieldTypes[fd.Number()]} diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go index 9488b7261..d9ea010be 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go @@ -10,17 +10,17 @@ import ( "google.golang.org/protobuf/internal/detrand" "google.golang.org/protobuf/internal/pragma" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type reflectMessageInfo struct { - fields map[pref.FieldNumber]*fieldInfo - oneofs map[pref.Name]*oneofInfo + fields map[protoreflect.FieldNumber]*fieldInfo + oneofs map[protoreflect.Name]*oneofInfo // fieldTypes contains the zero value of an enum or message field. // For lists, it contains the element type. // For maps, it contains the entry value type. - fieldTypes map[pref.FieldNumber]interface{} + fieldTypes map[protoreflect.FieldNumber]interface{} // denseFields is a subset of fields where: // 0 < fieldDesc.Number() < len(denseFields) @@ -30,8 +30,8 @@ type reflectMessageInfo struct { // rangeInfos is a list of all fields (not belonging to a oneof) and oneofs. rangeInfos []interface{} // either *fieldInfo or *oneofInfo - getUnknown func(pointer) pref.RawFields - setUnknown func(pointer, pref.RawFields) + getUnknown func(pointer) protoreflect.RawFields + setUnknown func(pointer, protoreflect.RawFields) extensionMap func(pointer) *extensionMap nilMessage atomicNilMessage @@ -52,7 +52,7 @@ func (mi *MessageInfo) makeReflectFuncs(t reflect.Type, si structInfo) { // This code assumes that the struct is well-formed and panics if there are // any discrepancies. func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) { - mi.fields = map[pref.FieldNumber]*fieldInfo{} + mi.fields = map[protoreflect.FieldNumber]*fieldInfo{} md := mi.Desc fds := md.Fields() for i := 0; i < fds.Len(); i++ { @@ -82,7 +82,7 @@ func (mi *MessageInfo) makeKnownFieldsFunc(si structInfo) { mi.fields[fd.Number()] = &fi } - mi.oneofs = map[pref.Name]*oneofInfo{} + mi.oneofs = map[protoreflect.Name]*oneofInfo{} for i := 0; i < md.Oneofs().Len(); i++ { od := md.Oneofs().Get(i) mi.oneofs[od.Name()] = makeOneofInfo(od, si, mi.Exporter) @@ -117,13 +117,13 @@ func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) { switch { case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsAType: // Handle as []byte. - mi.getUnknown = func(p pointer) pref.RawFields { + mi.getUnknown = func(p pointer) protoreflect.RawFields { if p.IsNil() { return nil } return *p.Apply(mi.unknownOffset).Bytes() } - mi.setUnknown = func(p pointer, b pref.RawFields) { + mi.setUnknown = func(p pointer, b protoreflect.RawFields) { if p.IsNil() { panic("invalid SetUnknown on nil Message") } @@ -131,7 +131,7 @@ func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) { } case si.unknownOffset.IsValid() && si.unknownType == unknownFieldsBType: // Handle as *[]byte. - mi.getUnknown = func(p pointer) pref.RawFields { + mi.getUnknown = func(p pointer) protoreflect.RawFields { if p.IsNil() { return nil } @@ -141,7 +141,7 @@ func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) { } return **bp } - mi.setUnknown = func(p pointer, b pref.RawFields) { + mi.setUnknown = func(p pointer, b protoreflect.RawFields) { if p.IsNil() { panic("invalid SetUnknown on nil Message") } @@ -152,10 +152,10 @@ func (mi *MessageInfo) makeUnknownFieldsFunc(t reflect.Type, si structInfo) { **bp = b } default: - mi.getUnknown = func(pointer) pref.RawFields { + mi.getUnknown = func(pointer) protoreflect.RawFields { return nil } - mi.setUnknown = func(p pointer, _ pref.RawFields) { + mi.setUnknown = func(p pointer, _ protoreflect.RawFields) { if p.IsNil() { panic("invalid SetUnknown on nil Message") } @@ -224,7 +224,7 @@ func (mi *MessageInfo) makeFieldTypes(si structInfo) { } if ft != nil { if mi.fieldTypes == nil { - mi.fieldTypes = make(map[pref.FieldNumber]interface{}) + mi.fieldTypes = make(map[protoreflect.FieldNumber]interface{}) } mi.fieldTypes[fd.Number()] = reflect.Zero(ft).Interface() } @@ -233,7 +233,7 @@ func (mi *MessageInfo) makeFieldTypes(si structInfo) { type extensionMap map[int32]ExtensionField -func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) { +func (m *extensionMap) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) { if m != nil { for _, x := range *m { xd := x.Type().TypeDescriptor() @@ -247,7 +247,7 @@ func (m *extensionMap) Range(f func(pref.FieldDescriptor, pref.Value) bool) { } } } -func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) { +func (m *extensionMap) Has(xt protoreflect.ExtensionType) (ok bool) { if m == nil { return false } @@ -266,10 +266,10 @@ func (m *extensionMap) Has(xt pref.ExtensionType) (ok bool) { } return true } -func (m *extensionMap) Clear(xt pref.ExtensionType) { +func (m *extensionMap) Clear(xt protoreflect.ExtensionType) { delete(*m, int32(xt.TypeDescriptor().Number())) } -func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value { +func (m *extensionMap) Get(xt protoreflect.ExtensionType) protoreflect.Value { xd := xt.TypeDescriptor() if m != nil { if x, ok := (*m)[int32(xd.Number())]; ok { @@ -278,7 +278,7 @@ func (m *extensionMap) Get(xt pref.ExtensionType) pref.Value { } return xt.Zero() } -func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) { +func (m *extensionMap) Set(xt protoreflect.ExtensionType, v protoreflect.Value) { xd := xt.TypeDescriptor() isValid := true switch { @@ -302,9 +302,9 @@ func (m *extensionMap) Set(xt pref.ExtensionType, v pref.Value) { x.Set(xt, v) (*m)[int32(xd.Number())] = x } -func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value { +func (m *extensionMap) Mutable(xt protoreflect.ExtensionType) protoreflect.Value { xd := xt.TypeDescriptor() - if xd.Kind() != pref.MessageKind && xd.Kind() != pref.GroupKind && !xd.IsList() && !xd.IsMap() { + if xd.Kind() != protoreflect.MessageKind && xd.Kind() != protoreflect.GroupKind && !xd.IsList() && !xd.IsMap() { panic("invalid Mutable on field with non-composite type") } if x, ok := (*m)[int32(xd.Number())]; ok { @@ -320,7 +320,6 @@ func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value { // in an allocation-free way without needing to have a shadow Go type generated // for every message type. This technique only works using unsafe. // -// // Example generated code: // // type M struct { @@ -351,12 +350,11 @@ func (m *extensionMap) Mutable(xt pref.ExtensionType) pref.Value { // It has access to the message info as its first field, and a pointer to the // MessageState is identical to a pointer to the concrete message value. // -// // Requirements: -// • The type M must implement protoreflect.ProtoMessage. -// • The address of m must not be nil. -// • The address of m and the address of m.state must be equal, -// even though they are different Go types. +// - The type M must implement protoreflect.ProtoMessage. +// - The address of m must not be nil. +// - The address of m and the address of m.state must be equal, +// even though they are different Go types. type MessageState struct { pragma.NoUnkeyedLiterals pragma.DoNotCompare @@ -368,8 +366,8 @@ type MessageState struct { type messageState MessageState var ( - _ pref.Message = (*messageState)(nil) - _ unwrapper = (*messageState)(nil) + _ protoreflect.Message = (*messageState)(nil) + _ unwrapper = (*messageState)(nil) ) // messageDataType is a tuple of a pointer to the message data and @@ -387,16 +385,16 @@ type ( ) var ( - _ pref.Message = (*messageReflectWrapper)(nil) - _ unwrapper = (*messageReflectWrapper)(nil) - _ pref.ProtoMessage = (*messageIfaceWrapper)(nil) - _ unwrapper = (*messageIfaceWrapper)(nil) + _ protoreflect.Message = (*messageReflectWrapper)(nil) + _ unwrapper = (*messageReflectWrapper)(nil) + _ protoreflect.ProtoMessage = (*messageIfaceWrapper)(nil) + _ unwrapper = (*messageIfaceWrapper)(nil) ) // MessageOf returns a reflective view over a message. The input must be a // pointer to a named Go struct. If the provided type has a ProtoReflect method, // it must be implemented by calling this method. -func (mi *MessageInfo) MessageOf(m interface{}) pref.Message { +func (mi *MessageInfo) MessageOf(m interface{}) protoreflect.Message { if reflect.TypeOf(m) != mi.GoReflectType { panic(fmt.Sprintf("type mismatch: got %T, want %v", m, mi.GoReflectType)) } @@ -421,7 +419,7 @@ func (m *messageIfaceWrapper) Reset() { rv.Elem().Set(reflect.Zero(rv.Type().Elem())) } } -func (m *messageIfaceWrapper) ProtoReflect() pref.Message { +func (m *messageIfaceWrapper) ProtoReflect() protoreflect.Message { return (*messageReflectWrapper)(m) } func (m *messageIfaceWrapper) protoUnwrap() interface{} { @@ -430,7 +428,7 @@ func (m *messageIfaceWrapper) protoUnwrap() interface{} { // checkField verifies that the provided field descriptor is valid. // Exactly one of the returned values is populated. -func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.ExtensionType) { +func (mi *MessageInfo) checkField(fd protoreflect.FieldDescriptor) (*fieldInfo, protoreflect.ExtensionType) { var fi *fieldInfo if n := fd.Number(); 0 < n && int(n) < len(mi.denseFields) { fi = mi.denseFields[n] @@ -455,7 +453,7 @@ func (mi *MessageInfo) checkField(fd pref.FieldDescriptor) (*fieldInfo, pref.Ext if !mi.Desc.ExtensionRanges().Has(fd.Number()) { panic(fmt.Sprintf("extension %v extends %v outside the extension range", fd.FullName(), mi.Desc.FullName())) } - xtd, ok := fd.(pref.ExtensionTypeDescriptor) + xtd, ok := fd.(protoreflect.ExtensionTypeDescriptor) if !ok { panic(fmt.Sprintf("extension %v does not implement protoreflect.ExtensionTypeDescriptor", fd.FullName())) } diff --git a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go index 343cf8721..5e736c60e 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go @@ -11,24 +11,24 @@ import ( "sync" "google.golang.org/protobuf/internal/flags" - pref "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" ) type fieldInfo struct { - fieldDesc pref.FieldDescriptor + fieldDesc protoreflect.FieldDescriptor // These fields are used for protobuf reflection support. has func(pointer) bool clear func(pointer) - get func(pointer) pref.Value - set func(pointer, pref.Value) - mutable func(pointer) pref.Value - newMessage func() pref.Message - newField func() pref.Value + get func(pointer) protoreflect.Value + set func(pointer, protoreflect.Value) + mutable func(pointer) protoreflect.Value + newMessage func() protoreflect.Message + newField func() protoreflect.Value } -func fieldInfoForMissing(fd pref.FieldDescriptor) fieldInfo { +func fieldInfoForMissing(fd protoreflect.FieldDescriptor) fieldInfo { // This never occurs for generated message types. // It implies that a hand-crafted type has missing Go fields // for specific protobuf message fields. @@ -40,19 +40,19 @@ func fieldInfoForMissing(fd pref.FieldDescriptor) fieldInfo { clear: func(p pointer) { panic("missing Go struct field for " + string(fd.FullName())) }, - get: func(p pointer) pref.Value { + get: func(p pointer) protoreflect.Value { return fd.Default() }, - set: func(p pointer, v pref.Value) { + set: func(p pointer, v protoreflect.Value) { panic("missing Go struct field for " + string(fd.FullName())) }, - mutable: func(p pointer) pref.Value { + mutable: func(p pointer) protoreflect.Value { panic("missing Go struct field for " + string(fd.FullName())) }, - newMessage: func() pref.Message { + newMessage: func() protoreflect.Message { panic("missing Go struct field for " + string(fd.FullName())) }, - newField: func() pref.Value { + newField: func() protoreflect.Value { if v := fd.Default(); v.IsValid() { return v } @@ -61,7 +61,7 @@ func fieldInfoForMissing(fd pref.FieldDescriptor) fieldInfo { } } -func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo { +func fieldInfoForOneof(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter, ot reflect.Type) fieldInfo { ft := fs.Type if ft.Kind() != reflect.Interface { panic(fmt.Sprintf("field %v has invalid type: got %v, want interface kind", fd.FullName(), ft)) @@ -102,7 +102,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export } rv.Set(reflect.Zero(rv.Type())) }, - get: func(p pointer) pref.Value { + get: func(p pointer) protoreflect.Value { if p.IsNil() { return conv.Zero() } @@ -113,7 +113,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export rv = rv.Elem().Elem().Field(0) return conv.PBValueOf(rv) }, - set: func(p pointer, v pref.Value) { + set: func(p pointer, v protoreflect.Value) { rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if rv.IsNil() || rv.Elem().Type().Elem() != ot || rv.Elem().IsNil() { rv.Set(reflect.New(ot)) @@ -121,7 +121,7 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export rv = rv.Elem().Elem().Field(0) rv.Set(conv.GoValueOf(v)) }, - mutable: func(p pointer) pref.Value { + mutable: func(p pointer) protoreflect.Value { if !isMessage { panic(fmt.Sprintf("field %v with invalid Mutable call on field with non-composite type", fd.FullName())) } @@ -131,20 +131,20 @@ func fieldInfoForOneof(fd pref.FieldDescriptor, fs reflect.StructField, x export } rv = rv.Elem().Elem().Field(0) if rv.Kind() == reflect.Ptr && rv.IsNil() { - rv.Set(conv.GoValueOf(pref.ValueOfMessage(conv.New().Message()))) + rv.Set(conv.GoValueOf(protoreflect.ValueOfMessage(conv.New().Message()))) } return conv.PBValueOf(rv) }, - newMessage: func() pref.Message { + newMessage: func() protoreflect.Message { return conv.New().Message() }, - newField: func() pref.Value { + newField: func() protoreflect.Value { return conv.New() }, } } -func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { +func fieldInfoForMap(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { ft := fs.Type if ft.Kind() != reflect.Map { panic(fmt.Sprintf("field %v has invalid type: got %v, want map kind", fd.FullName(), ft)) @@ -166,7 +166,7 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv.Set(reflect.Zero(rv.Type())) }, - get: func(p pointer) pref.Value { + get: func(p pointer) protoreflect.Value { if p.IsNil() { return conv.Zero() } @@ -176,7 +176,7 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter } return conv.PBValueOf(rv) }, - set: func(p pointer, v pref.Value) { + set: func(p pointer, v protoreflect.Value) { rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() pv := conv.GoValueOf(v) if pv.IsNil() { @@ -184,20 +184,20 @@ func fieldInfoForMap(fd pref.FieldDescriptor, fs reflect.StructField, x exporter } rv.Set(pv) }, - mutable: func(p pointer) pref.Value { + mutable: func(p pointer) protoreflect.Value { v := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if v.IsNil() { v.Set(reflect.MakeMap(fs.Type)) } return conv.PBValueOf(v) }, - newField: func() pref.Value { + newField: func() protoreflect.Value { return conv.New() }, } } -func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { +func fieldInfoForList(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { ft := fs.Type if ft.Kind() != reflect.Slice { panic(fmt.Sprintf("field %v has invalid type: got %v, want slice kind", fd.FullName(), ft)) @@ -219,7 +219,7 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporte rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv.Set(reflect.Zero(rv.Type())) }, - get: func(p pointer) pref.Value { + get: func(p pointer) protoreflect.Value { if p.IsNil() { return conv.Zero() } @@ -229,7 +229,7 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporte } return conv.PBValueOf(rv) }, - set: func(p pointer, v pref.Value) { + set: func(p pointer, v protoreflect.Value) { rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() pv := conv.GoValueOf(v) if pv.IsNil() { @@ -237,11 +237,11 @@ func fieldInfoForList(fd pref.FieldDescriptor, fs reflect.StructField, x exporte } rv.Set(pv.Elem()) }, - mutable: func(p pointer) pref.Value { + mutable: func(p pointer) protoreflect.Value { v := p.Apply(fieldOffset).AsValueOf(fs.Type) return conv.PBValueOf(v) }, - newField: func() pref.Value { + newField: func() protoreflect.Value { return conv.New() }, } @@ -252,7 +252,7 @@ var ( emptyBytes = reflect.ValueOf([]byte{}) ) -func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { +func fieldInfoForScalar(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { ft := fs.Type nullable := fd.HasPresence() isBytes := ft.Kind() == reflect.Slice && ft.Elem().Kind() == reflect.Uint8 @@ -300,7 +300,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv.Set(reflect.Zero(rv.Type())) }, - get: func(p pointer) pref.Value { + get: func(p pointer) protoreflect.Value { if p.IsNil() { return conv.Zero() } @@ -315,7 +315,7 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor } return conv.PBValueOf(rv) }, - set: func(p pointer, v pref.Value) { + set: func(p pointer, v protoreflect.Value) { rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if nullable && rv.Kind() == reflect.Ptr { if rv.IsNil() { @@ -332,23 +332,23 @@ func fieldInfoForScalar(fd pref.FieldDescriptor, fs reflect.StructField, x expor } } }, - newField: func() pref.Value { + newField: func() protoreflect.Value { return conv.New() }, } } -func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldInfo { +func fieldInfoForWeakMessage(fd protoreflect.FieldDescriptor, weakOffset offset) fieldInfo { if !flags.ProtoLegacy { panic("no support for proto1 weak fields") } var once sync.Once - var messageType pref.MessageType + var messageType protoreflect.MessageType lazyInit := func() { once.Do(func() { messageName := fd.Message().FullName() - messageType, _ = preg.GlobalTypes.FindMessageByName(messageName) + messageType, _ = protoregistry.GlobalTypes.FindMessageByName(messageName) if messageType == nil { panic(fmt.Sprintf("weak message %v for field %v is not linked in", messageName, fd.FullName())) } @@ -368,18 +368,18 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn clear: func(p pointer) { p.Apply(weakOffset).WeakFields().clear(num) }, - get: func(p pointer) pref.Value { + get: func(p pointer) protoreflect.Value { lazyInit() if p.IsNil() { - return pref.ValueOfMessage(messageType.Zero()) + return protoreflect.ValueOfMessage(messageType.Zero()) } m, ok := p.Apply(weakOffset).WeakFields().get(num) if !ok { - return pref.ValueOfMessage(messageType.Zero()) + return protoreflect.ValueOfMessage(messageType.Zero()) } - return pref.ValueOfMessage(m.ProtoReflect()) + return protoreflect.ValueOfMessage(m.ProtoReflect()) }, - set: func(p pointer, v pref.Value) { + set: func(p pointer, v protoreflect.Value) { lazyInit() m := v.Message() if m.Descriptor() != messageType.Descriptor() { @@ -390,7 +390,7 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn } p.Apply(weakOffset).WeakFields().set(num, m.Interface()) }, - mutable: func(p pointer) pref.Value { + mutable: func(p pointer) protoreflect.Value { lazyInit() fs := p.Apply(weakOffset).WeakFields() m, ok := fs.get(num) @@ -398,20 +398,20 @@ func fieldInfoForWeakMessage(fd pref.FieldDescriptor, weakOffset offset) fieldIn m = messageType.New().Interface() fs.set(num, m) } - return pref.ValueOfMessage(m.ProtoReflect()) + return protoreflect.ValueOfMessage(m.ProtoReflect()) }, - newMessage: func() pref.Message { + newMessage: func() protoreflect.Message { lazyInit() return messageType.New() }, - newField: func() pref.Value { + newField: func() protoreflect.Value { lazyInit() - return pref.ValueOfMessage(messageType.New()) + return protoreflect.ValueOfMessage(messageType.New()) }, } } -func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { +func fieldInfoForMessage(fd protoreflect.FieldDescriptor, fs reflect.StructField, x exporter) fieldInfo { ft := fs.Type conv := NewConverter(ft, fd) @@ -433,47 +433,47 @@ func fieldInfoForMessage(fd pref.FieldDescriptor, fs reflect.StructField, x expo rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv.Set(reflect.Zero(rv.Type())) }, - get: func(p pointer) pref.Value { + get: func(p pointer) protoreflect.Value { if p.IsNil() { return conv.Zero() } rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() return conv.PBValueOf(rv) }, - set: func(p pointer, v pref.Value) { + set: func(p pointer, v protoreflect.Value) { rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() rv.Set(conv.GoValueOf(v)) if fs.Type.Kind() == reflect.Ptr && rv.IsNil() { panic(fmt.Sprintf("field %v has invalid nil pointer", fd.FullName())) } }, - mutable: func(p pointer) pref.Value { + mutable: func(p pointer) protoreflect.Value { rv := p.Apply(fieldOffset).AsValueOf(fs.Type).Elem() if fs.Type.Kind() == reflect.Ptr && rv.IsNil() { rv.Set(conv.GoValueOf(conv.New())) } return conv.PBValueOf(rv) }, - newMessage: func() pref.Message { + newMessage: func() protoreflect.Message { return conv.New().Message() }, - newField: func() pref.Value { + newField: func() protoreflect.Value { return conv.New() }, } } type oneofInfo struct { - oneofDesc pref.OneofDescriptor - which func(pointer) pref.FieldNumber + oneofDesc protoreflect.OneofDescriptor + which func(pointer) protoreflect.FieldNumber } -func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInfo { +func makeOneofInfo(od protoreflect.OneofDescriptor, si structInfo, x exporter) *oneofInfo { oi := &oneofInfo{oneofDesc: od} if od.IsSynthetic() { fs := si.fieldsByNumber[od.Fields().Get(0).Number()] fieldOffset := offsetOf(fs, x) - oi.which = func(p pointer) pref.FieldNumber { + oi.which = func(p pointer) protoreflect.FieldNumber { if p.IsNil() { return 0 } @@ -486,7 +486,7 @@ func makeOneofInfo(od pref.OneofDescriptor, si structInfo, x exporter) *oneofInf } else { fs := si.oneofsByName[od.Name()] fieldOffset := offsetOf(fs, x) - oi.which = func(p pointer) pref.FieldNumber { + oi.which = func(p pointer) protoreflect.FieldNumber { if p.IsNil() { return 0 } diff --git a/vendor/google.golang.org/protobuf/internal/impl/validate.go b/vendor/google.golang.org/protobuf/internal/impl/validate.go index 08cfb6054..a24e6bbd7 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/validate.go +++ b/vendor/google.golang.org/protobuf/internal/impl/validate.go @@ -16,9 +16,9 @@ import ( "google.golang.org/protobuf/internal/flags" "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" - pref "google.golang.org/protobuf/reflect/protoreflect" - preg "google.golang.org/protobuf/reflect/protoregistry" - piface "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoiface" ) // ValidationStatus is the result of validating the wire-format encoding of a message. @@ -56,20 +56,20 @@ func (v ValidationStatus) String() string { // of the message type. // // This function is exposed for testing. -func Validate(mt pref.MessageType, in piface.UnmarshalInput) (out piface.UnmarshalOutput, _ ValidationStatus) { +func Validate(mt protoreflect.MessageType, in protoiface.UnmarshalInput) (out protoiface.UnmarshalOutput, _ ValidationStatus) { mi, ok := mt.(*MessageInfo) if !ok { return out, ValidationUnknown } if in.Resolver == nil { - in.Resolver = preg.GlobalTypes + in.Resolver = protoregistry.GlobalTypes } o, st := mi.validate(in.Buf, 0, unmarshalOptions{ flags: in.Flags, resolver: in.Resolver, }) if o.initialized { - out.Flags |= piface.UnmarshalInitialized + out.Flags |= protoiface.UnmarshalInitialized } return out, st } @@ -106,22 +106,22 @@ const ( validationTypeMessageSetItem ) -func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescriptor, ft reflect.Type) validationInfo { +func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd protoreflect.FieldDescriptor, ft reflect.Type) validationInfo { var vi validationInfo switch { case fd.ContainingOneof() != nil && !fd.ContainingOneof().IsSynthetic(): switch fd.Kind() { - case pref.MessageKind: + case protoreflect.MessageKind: vi.typ = validationTypeMessage if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok { vi.mi = getMessageInfo(ot.Field(0).Type) } - case pref.GroupKind: + case protoreflect.GroupKind: vi.typ = validationTypeGroup if ot, ok := si.oneofWrappersByNumber[fd.Number()]; ok { vi.mi = getMessageInfo(ot.Field(0).Type) } - case pref.StringKind: + case protoreflect.StringKind: if strs.EnforceUTF8(fd) { vi.typ = validationTypeUTF8String } @@ -129,7 +129,7 @@ func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescrip default: vi = newValidationInfo(fd, ft) } - if fd.Cardinality() == pref.Required { + if fd.Cardinality() == protoreflect.Required { // Avoid overflow. The required field check is done with a 64-bit mask, with // any message containing more than 64 required fields always reported as // potentially uninitialized, so it is not important to get a precise count @@ -142,22 +142,22 @@ func newFieldValidationInfo(mi *MessageInfo, si structInfo, fd pref.FieldDescrip return vi } -func newValidationInfo(fd pref.FieldDescriptor, ft reflect.Type) validationInfo { +func newValidationInfo(fd protoreflect.FieldDescriptor, ft reflect.Type) validationInfo { var vi validationInfo switch { case fd.IsList(): switch fd.Kind() { - case pref.MessageKind: + case protoreflect.MessageKind: vi.typ = validationTypeMessage if ft.Kind() == reflect.Slice { vi.mi = getMessageInfo(ft.Elem()) } - case pref.GroupKind: + case protoreflect.GroupKind: vi.typ = validationTypeGroup if ft.Kind() == reflect.Slice { vi.mi = getMessageInfo(ft.Elem()) } - case pref.StringKind: + case protoreflect.StringKind: vi.typ = validationTypeBytes if strs.EnforceUTF8(fd) { vi.typ = validationTypeUTF8String @@ -175,33 +175,33 @@ func newValidationInfo(fd pref.FieldDescriptor, ft reflect.Type) validationInfo case fd.IsMap(): vi.typ = validationTypeMap switch fd.MapKey().Kind() { - case pref.StringKind: + case protoreflect.StringKind: if strs.EnforceUTF8(fd) { vi.keyType = validationTypeUTF8String } } switch fd.MapValue().Kind() { - case pref.MessageKind: + case protoreflect.MessageKind: vi.valType = validationTypeMessage if ft.Kind() == reflect.Map { vi.mi = getMessageInfo(ft.Elem()) } - case pref.StringKind: + case protoreflect.StringKind: if strs.EnforceUTF8(fd) { vi.valType = validationTypeUTF8String } } default: switch fd.Kind() { - case pref.MessageKind: + case protoreflect.MessageKind: vi.typ = validationTypeMessage if !fd.IsWeak() { vi.mi = getMessageInfo(ft) } - case pref.GroupKind: + case protoreflect.GroupKind: vi.typ = validationTypeGroup vi.mi = getMessageInfo(ft) - case pref.StringKind: + case protoreflect.StringKind: vi.typ = validationTypeBytes if strs.EnforceUTF8(fd) { vi.typ = validationTypeUTF8String @@ -314,11 +314,11 @@ State: break } messageName := fd.Message().FullName() - messageType, err := preg.GlobalTypes.FindMessageByName(messageName) + messageType, err := protoregistry.GlobalTypes.FindMessageByName(messageName) switch err { case nil: vi.mi, _ = messageType.(*MessageInfo) - case preg.NotFound: + case protoregistry.NotFound: vi.typ = validationTypeBytes default: return out, ValidationUnknown @@ -335,7 +335,7 @@ State: // unmarshaling to begin failing. Supporting this requires some way to // determine if the resolver is frozen. xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), num) - if err != nil && err != preg.NotFound { + if err != nil && err != protoregistry.NotFound { return out, ValidationUnknown } if err == nil { @@ -513,7 +513,7 @@ State: } xt, err := opts.resolver.FindExtensionByNumber(st.mi.Desc.FullName(), typeid) switch { - case err == preg.NotFound: + case err == protoregistry.NotFound: b = b[n:] case err != nil: return out, ValidationUnknown diff --git a/vendor/google.golang.org/protobuf/internal/impl/weak.go b/vendor/google.golang.org/protobuf/internal/impl/weak.go index 009cbefd1..eb79a7ba9 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/weak.go +++ b/vendor/google.golang.org/protobuf/internal/impl/weak.go @@ -7,7 +7,7 @@ package impl import ( "fmt" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" ) @@ -17,32 +17,32 @@ import ( // defined directly on it. type weakFields WeakFields -func (w weakFields) get(num pref.FieldNumber) (pref.ProtoMessage, bool) { +func (w weakFields) get(num protoreflect.FieldNumber) (protoreflect.ProtoMessage, bool) { m, ok := w[int32(num)] return m, ok } -func (w *weakFields) set(num pref.FieldNumber, m pref.ProtoMessage) { +func (w *weakFields) set(num protoreflect.FieldNumber, m protoreflect.ProtoMessage) { if *w == nil { *w = make(weakFields) } (*w)[int32(num)] = m } -func (w *weakFields) clear(num pref.FieldNumber) { +func (w *weakFields) clear(num protoreflect.FieldNumber) { delete(*w, int32(num)) } -func (Export) HasWeak(w WeakFields, num pref.FieldNumber) bool { +func (Export) HasWeak(w WeakFields, num protoreflect.FieldNumber) bool { _, ok := w[int32(num)] return ok } -func (Export) ClearWeak(w *WeakFields, num pref.FieldNumber) { +func (Export) ClearWeak(w *WeakFields, num protoreflect.FieldNumber) { delete(*w, int32(num)) } -func (Export) GetWeak(w WeakFields, num pref.FieldNumber, name pref.FullName) pref.ProtoMessage { +func (Export) GetWeak(w WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName) protoreflect.ProtoMessage { if m, ok := w[int32(num)]; ok { return m } @@ -53,7 +53,7 @@ func (Export) GetWeak(w WeakFields, num pref.FieldNumber, name pref.FullName) pr return mt.Zero().Interface() } -func (Export) SetWeak(w *WeakFields, num pref.FieldNumber, name pref.FullName, m pref.ProtoMessage) { +func (Export) SetWeak(w *WeakFields, num protoreflect.FieldNumber, name protoreflect.FullName, m protoreflect.ProtoMessage) { if m != nil { mt, _ := protoregistry.GlobalTypes.FindMessageByName(name) if mt == nil { diff --git a/vendor/google.golang.org/protobuf/internal/order/order.go b/vendor/google.golang.org/protobuf/internal/order/order.go index 2a24953f6..33745ed06 100644 --- a/vendor/google.golang.org/protobuf/internal/order/order.go +++ b/vendor/google.golang.org/protobuf/internal/order/order.go @@ -5,12 +5,12 @@ package order import ( - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) // FieldOrder specifies the ordering to visit message fields. // It is a function that reports whether x is ordered before y. -type FieldOrder func(x, y pref.FieldDescriptor) bool +type FieldOrder func(x, y protoreflect.FieldDescriptor) bool var ( // AnyFieldOrder specifies no specific field ordering. @@ -18,9 +18,9 @@ var ( // LegacyFieldOrder sorts fields in the same ordering as emitted by // wire serialization in the github.com/golang/protobuf implementation. - LegacyFieldOrder FieldOrder = func(x, y pref.FieldDescriptor) bool { + LegacyFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool { ox, oy := x.ContainingOneof(), y.ContainingOneof() - inOneof := func(od pref.OneofDescriptor) bool { + inOneof := func(od protoreflect.OneofDescriptor) bool { return od != nil && !od.IsSynthetic() } @@ -41,14 +41,14 @@ var ( } // NumberFieldOrder sorts fields by their field number. - NumberFieldOrder FieldOrder = func(x, y pref.FieldDescriptor) bool { + NumberFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool { return x.Number() < y.Number() } // IndexNameFieldOrder sorts non-extension fields before extension fields. // Non-extensions are sorted according to their declaration index. // Extensions are sorted according to their full name. - IndexNameFieldOrder FieldOrder = func(x, y pref.FieldDescriptor) bool { + IndexNameFieldOrder FieldOrder = func(x, y protoreflect.FieldDescriptor) bool { // Non-extension fields sort before extension fields. if x.IsExtension() != y.IsExtension() { return !x.IsExtension() && y.IsExtension() @@ -64,7 +64,7 @@ var ( // KeyOrder specifies the ordering to visit map entries. // It is a function that reports whether x is ordered before y. -type KeyOrder func(x, y pref.MapKey) bool +type KeyOrder func(x, y protoreflect.MapKey) bool var ( // AnyKeyOrder specifies no specific key ordering. @@ -72,7 +72,7 @@ var ( // GenericKeyOrder sorts false before true, numeric keys in ascending order, // and strings in lexicographical ordering according to UTF-8 codepoints. - GenericKeyOrder KeyOrder = func(x, y pref.MapKey) bool { + GenericKeyOrder KeyOrder = func(x, y protoreflect.MapKey) bool { switch x.Interface().(type) { case bool: return !x.Bool() && y.Bool() diff --git a/vendor/google.golang.org/protobuf/internal/order/range.go b/vendor/google.golang.org/protobuf/internal/order/range.go index c8090e0c5..1665a68e5 100644 --- a/vendor/google.golang.org/protobuf/internal/order/range.go +++ b/vendor/google.golang.org/protobuf/internal/order/range.go @@ -9,12 +9,12 @@ import ( "sort" "sync" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type messageField struct { - fd pref.FieldDescriptor - v pref.Value + fd protoreflect.FieldDescriptor + v protoreflect.Value } var messageFieldPool = sync.Pool{ @@ -25,8 +25,8 @@ type ( // FieldRnger is an interface for visiting all fields in a message. // The protoreflect.Message type implements this interface. FieldRanger interface{ Range(VisitField) } - // VisitField is called everytime a message field is visited. - VisitField = func(pref.FieldDescriptor, pref.Value) bool + // VisitField is called every time a message field is visited. + VisitField = func(protoreflect.FieldDescriptor, protoreflect.Value) bool ) // RangeFields iterates over the fields of fs according to the specified order. @@ -47,7 +47,7 @@ func RangeFields(fs FieldRanger, less FieldOrder, fn VisitField) { }() // Collect all fields in the message and sort them. - fs.Range(func(fd pref.FieldDescriptor, v pref.Value) bool { + fs.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { fields = append(fields, messageField{fd, v}) return true }) @@ -64,8 +64,8 @@ func RangeFields(fs FieldRanger, less FieldOrder, fn VisitField) { } type mapEntry struct { - k pref.MapKey - v pref.Value + k protoreflect.MapKey + v protoreflect.Value } var mapEntryPool = sync.Pool{ @@ -76,8 +76,8 @@ type ( // EntryRanger is an interface for visiting all fields in a message. // The protoreflect.Map type implements this interface. EntryRanger interface{ Range(VisitEntry) } - // VisitEntry is called everytime a map entry is visited. - VisitEntry = func(pref.MapKey, pref.Value) bool + // VisitEntry is called every time a map entry is visited. + VisitEntry = func(protoreflect.MapKey, protoreflect.Value) bool ) // RangeEntries iterates over the entries of es according to the specified order. @@ -98,7 +98,7 @@ func RangeEntries(es EntryRanger, less KeyOrder, fn VisitEntry) { }() // Collect all entries in the map and sort them. - es.Range(func(k pref.MapKey, v pref.Value) bool { + es.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { entries = append(entries, mapEntry{k, v}) return true }) diff --git a/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go b/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go index 56a8a4ed3..fea589c45 100644 --- a/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go +++ b/vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go @@ -10,7 +10,7 @@ package strs import ( "unsafe" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) type ( @@ -59,7 +59,7 @@ type Builder struct { // AppendFullName is equivalent to protoreflect.FullName.Append, // but optimized for large batches where each name has a shared lifetime. -func (sb *Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.FullName { +func (sb *Builder) AppendFullName(prefix protoreflect.FullName, name protoreflect.Name) protoreflect.FullName { n := len(prefix) + len(".") + len(name) if len(prefix) == 0 { n -= len(".") @@ -68,7 +68,7 @@ func (sb *Builder) AppendFullName(prefix pref.FullName, name pref.Name) pref.Ful sb.buf = append(sb.buf, prefix...) sb.buf = append(sb.buf, '.') sb.buf = append(sb.buf, name...) - return pref.FullName(sb.last(n)) + return protoreflect.FullName(sb.last(n)) } // MakeString is equivalent to string(b), but optimized for large batches diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 3d40d5249..b480c5010 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -12,54 +12,54 @@ import ( // These constants determine the current version of this module. // -// // For our release process, we enforce the following rules: -// * Tagged releases use a tag that is identical to String. -// * Tagged releases never reference a commit where the String -// contains "devel". -// * The set of all commits in this repository where String -// does not contain "devel" must have a unique String. -// +// - Tagged releases use a tag that is identical to String. +// - Tagged releases never reference a commit where the String +// contains "devel". +// - The set of all commits in this repository where String +// does not contain "devel" must have a unique String. // // Steps for tagging a new release: -// 1. Create a new CL. // -// 2. Update Minor, Patch, and/or PreRelease as necessary. -// PreRelease must not contain the string "devel". +// 1. Create a new CL. // -// 3. Since the last released minor version, have there been any changes to -// generator that relies on new functionality in the runtime? -// If yes, then increment RequiredGenerated. +// 2. Update Minor, Patch, and/or PreRelease as necessary. +// PreRelease must not contain the string "devel". // -// 4. Since the last released minor version, have there been any changes to -// the runtime that removes support for old .pb.go source code? -// If yes, then increment SupportMinimum. +// 3. Since the last released minor version, have there been any changes to +// generator that relies on new functionality in the runtime? +// If yes, then increment RequiredGenerated. // -// 5. Send out the CL for review and submit it. -// Note that the next CL in step 8 must be submitted after this CL -// without any other CLs in-between. +// 4. Since the last released minor version, have there been any changes to +// the runtime that removes support for old .pb.go source code? +// If yes, then increment SupportMinimum. // -// 6. Tag a new version, where the tag is is the current String. +// 5. Send out the CL for review and submit it. +// Note that the next CL in step 8 must be submitted after this CL +// without any other CLs in-between. // -// 7. Write release notes for all notable changes -// between this release and the last release. +// 6. Tag a new version, where the tag is is the current String. // -// 8. Create a new CL. +// 7. Write release notes for all notable changes +// between this release and the last release. // -// 9. Update PreRelease to include the string "devel". -// For example: "" -> "devel" or "rc.1" -> "rc.1.devel" +// 8. Create a new CL. // -// 10. Send out the CL for review and submit it. +// 9. Update PreRelease to include the string "devel". +// For example: "" -> "devel" or "rc.1" -> "rc.1.devel" +// +// 10. Send out the CL for review and submit it. const ( Major = 1 Minor = 28 - Patch = 0 + Patch = 1 PreRelease = "" ) // String formats the version string for this module in semver format. // // Examples: +// // v1.20.1 // v1.21.0-rc.1 func String() string { diff --git a/vendor/google.golang.org/protobuf/proto/decode.go b/vendor/google.golang.org/protobuf/proto/decode.go index 11bf7173b..48d47946b 100644 --- a/vendor/google.golang.org/protobuf/proto/decode.go +++ b/vendor/google.golang.org/protobuf/proto/decode.go @@ -19,7 +19,8 @@ import ( // UnmarshalOptions configures the unmarshaler. // // Example usage: -// err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m) +// +// err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m) type UnmarshalOptions struct { pragma.NoUnkeyedLiterals diff --git a/vendor/google.golang.org/protobuf/proto/doc.go b/vendor/google.golang.org/protobuf/proto/doc.go index c52d8c4ab..08d2a46f5 100644 --- a/vendor/google.golang.org/protobuf/proto/doc.go +++ b/vendor/google.golang.org/protobuf/proto/doc.go @@ -6,18 +6,17 @@ // // For documentation on protocol buffers in general, see: // -// https://developers.google.com/protocol-buffers +// https://developers.google.com/protocol-buffers // // For a tutorial on using protocol buffers with Go, see: // -// https://developers.google.com/protocol-buffers/docs/gotutorial +// https://developers.google.com/protocol-buffers/docs/gotutorial // // For a guide to generated Go protocol buffer code, see: // -// https://developers.google.com/protocol-buffers/docs/reference/go-generated +// https://developers.google.com/protocol-buffers/docs/reference/go-generated // -// -// Binary serialization +// # Binary serialization // // This package contains functions to convert to and from the wire format, // an efficient binary serialization of protocol buffers. @@ -30,8 +29,7 @@ // • Unmarshal converts a message from the wire format. // The UnmarshalOptions type provides more control over wire unmarshaling. // -// -// Basic message operations +// # Basic message operations // // • Clone makes a deep copy of a message. // @@ -45,8 +43,7 @@ // // • CheckInitialized reports whether all required fields in a message are set. // -// -// Optional scalar constructors +// # Optional scalar constructors // // The API for some generated messages represents optional scalar fields // as pointers to a value. For example, an optional string field has the @@ -61,16 +58,14 @@ // // Optional scalar fields are only supported in proto2. // -// -// Extension accessors +// # Extension accessors // // • HasExtension, GetExtension, SetExtension, and ClearExtension // access extension field values in a protocol buffer message. // // Extension fields are only supported in proto2. // -// -// Related packages +// # Related packages // // • Package "google.golang.org/protobuf/encoding/protojson" converts messages to // and from JSON. diff --git a/vendor/google.golang.org/protobuf/proto/encode.go b/vendor/google.golang.org/protobuf/proto/encode.go index d18239c23..bf7f816d0 100644 --- a/vendor/google.golang.org/protobuf/proto/encode.go +++ b/vendor/google.golang.org/protobuf/proto/encode.go @@ -16,7 +16,8 @@ import ( // MarshalOptions configures the marshaler. // // Example usage: -// b, err := MarshalOptions{Deterministic: true}.Marshal(m) +// +// b, err := MarshalOptions{Deterministic: true}.Marshal(m) type MarshalOptions struct { pragma.NoUnkeyedLiterals @@ -101,7 +102,9 @@ func (o MarshalOptions) Marshal(m Message) ([]byte, error) { // otherwise it returns a non-nil empty buffer. // // This is to assist the edge-case where user-code does the following: +// // m1.OptionalBytes, _ = proto.Marshal(m2) +// // where they expect the proto2 "optional_bytes" field to be populated // if any only if m2 is a valid message. func emptyBytesForMessage(m Message) []byte { diff --git a/vendor/google.golang.org/protobuf/proto/equal.go b/vendor/google.golang.org/protobuf/proto/equal.go index 4dba2b969..67948dd1d 100644 --- a/vendor/google.golang.org/protobuf/proto/equal.go +++ b/vendor/google.golang.org/protobuf/proto/equal.go @@ -10,7 +10,7 @@ import ( "reflect" "google.golang.org/protobuf/encoding/protowire" - pref "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoreflect" ) // Equal reports whether two messages are equal. @@ -33,6 +33,10 @@ func Equal(x, y Message) bool { if x == nil || y == nil { return x == nil && y == nil } + if reflect.TypeOf(x).Kind() == reflect.Ptr && x == y { + // Avoid an expensive comparison if both inputs are identical pointers. + return true + } mx := x.ProtoReflect() my := y.ProtoReflect() if mx.IsValid() != my.IsValid() { @@ -42,14 +46,14 @@ func Equal(x, y Message) bool { } // equalMessage compares two messages. -func equalMessage(mx, my pref.Message) bool { +func equalMessage(mx, my protoreflect.Message) bool { if mx.Descriptor() != my.Descriptor() { return false } nx := 0 equal := true - mx.Range(func(fd pref.FieldDescriptor, vx pref.Value) bool { + mx.Range(func(fd protoreflect.FieldDescriptor, vx protoreflect.Value) bool { nx++ vy := my.Get(fd) equal = my.Has(fd) && equalField(fd, vx, vy) @@ -59,7 +63,7 @@ func equalMessage(mx, my pref.Message) bool { return false } ny := 0 - my.Range(func(fd pref.FieldDescriptor, vx pref.Value) bool { + my.Range(func(fd protoreflect.FieldDescriptor, vx protoreflect.Value) bool { ny++ return true }) @@ -71,7 +75,7 @@ func equalMessage(mx, my pref.Message) bool { } // equalField compares two fields. -func equalField(fd pref.FieldDescriptor, x, y pref.Value) bool { +func equalField(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool { switch { case fd.IsList(): return equalList(fd, x.List(), y.List()) @@ -83,12 +87,12 @@ func equalField(fd pref.FieldDescriptor, x, y pref.Value) bool { } // equalMap compares two maps. -func equalMap(fd pref.FieldDescriptor, x, y pref.Map) bool { +func equalMap(fd protoreflect.FieldDescriptor, x, y protoreflect.Map) bool { if x.Len() != y.Len() { return false } equal := true - x.Range(func(k pref.MapKey, vx pref.Value) bool { + x.Range(func(k protoreflect.MapKey, vx protoreflect.Value) bool { vy := y.Get(k) equal = y.Has(k) && equalValue(fd.MapValue(), vx, vy) return equal @@ -97,7 +101,7 @@ func equalMap(fd pref.FieldDescriptor, x, y pref.Map) bool { } // equalList compares two lists. -func equalList(fd pref.FieldDescriptor, x, y pref.List) bool { +func equalList(fd protoreflect.FieldDescriptor, x, y protoreflect.List) bool { if x.Len() != y.Len() { return false } @@ -110,31 +114,31 @@ func equalList(fd pref.FieldDescriptor, x, y pref.List) bool { } // equalValue compares two singular values. -func equalValue(fd pref.FieldDescriptor, x, y pref.Value) bool { +func equalValue(fd protoreflect.FieldDescriptor, x, y protoreflect.Value) bool { switch fd.Kind() { - case pref.BoolKind: + case protoreflect.BoolKind: return x.Bool() == y.Bool() - case pref.EnumKind: + case protoreflect.EnumKind: return x.Enum() == y.Enum() - case pref.Int32Kind, pref.Sint32Kind, - pref.Int64Kind, pref.Sint64Kind, - pref.Sfixed32Kind, pref.Sfixed64Kind: + case protoreflect.Int32Kind, protoreflect.Sint32Kind, + protoreflect.Int64Kind, protoreflect.Sint64Kind, + protoreflect.Sfixed32Kind, protoreflect.Sfixed64Kind: return x.Int() == y.Int() - case pref.Uint32Kind, pref.Uint64Kind, - pref.Fixed32Kind, pref.Fixed64Kind: + case protoreflect.Uint32Kind, protoreflect.Uint64Kind, + protoreflect.Fixed32Kind, protoreflect.Fixed64Kind: return x.Uint() == y.Uint() - case pref.FloatKind, pref.DoubleKind: + case protoreflect.FloatKind, protoreflect.DoubleKind: fx := x.Float() fy := y.Float() if math.IsNaN(fx) || math.IsNaN(fy) { return math.IsNaN(fx) && math.IsNaN(fy) } return fx == fy - case pref.StringKind: + case protoreflect.StringKind: return x.String() == y.String() - case pref.BytesKind: + case protoreflect.BytesKind: return bytes.Equal(x.Bytes(), y.Bytes()) - case pref.MessageKind, pref.GroupKind: + case protoreflect.MessageKind, protoreflect.GroupKind: return equalMessage(x.Message(), y.Message()) default: return x.Interface() == y.Interface() @@ -143,7 +147,7 @@ func equalValue(fd pref.FieldDescriptor, x, y pref.Value) bool { // equalUnknown compares unknown fields by direct comparison on the raw bytes // of each individual field number. -func equalUnknown(x, y pref.RawFields) bool { +func equalUnknown(x, y protoreflect.RawFields) bool { if len(x) != len(y) { return false } @@ -151,8 +155,8 @@ func equalUnknown(x, y pref.RawFields) bool { return true } - mx := make(map[pref.FieldNumber]pref.RawFields) - my := make(map[pref.FieldNumber]pref.RawFields) + mx := make(map[protoreflect.FieldNumber]protoreflect.RawFields) + my := make(map[protoreflect.FieldNumber]protoreflect.RawFields) for len(x) > 0 { fnum, _, n := protowire.ConsumeField(x) mx[fnum] = append(mx[fnum], x[:n]...) diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go index cebb36cda..27d7e3501 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_resolve.go @@ -155,9 +155,9 @@ func (r *resolver) findTarget(k protoreflect.Kind, scope protoreflect.FullName, // // Suppose the scope was "fizz.buzz" and the reference was "Foo.Bar", // then the following full names are searched: -// * fizz.buzz.Foo.Bar -// * fizz.Foo.Bar -// * Foo.Bar +// - fizz.buzz.Foo.Bar +// - fizz.Foo.Bar +// - Foo.Bar func (r *resolver) findDescriptor(scope protoreflect.FullName, ref partialName) (protoreflect.Descriptor, error) { if !ref.IsValid() { return nil, errors.New("invalid name reference: %q", ref) diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go index dd85915bd..55aa14922 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go @@ -8,8 +8,7 @@ // defined in proto source files and value interfaces which provide the // ability to examine and manipulate the contents of messages. // -// -// Protocol Buffer Descriptors +// # Protocol Buffer Descriptors // // Protobuf descriptors (e.g., EnumDescriptor or MessageDescriptor) // are immutable objects that represent protobuf type information. @@ -26,8 +25,7 @@ // The "google.golang.org/protobuf/reflect/protodesc" package converts between // google.protobuf.DescriptorProto messages and protobuf descriptors. // -// -// Go Type Descriptors +// # Go Type Descriptors // // A type descriptor (e.g., EnumType or MessageType) is a constructor for // a concrete Go type that represents the associated protobuf descriptor. @@ -41,8 +39,7 @@ // The "google.golang.org/protobuf/types/dynamicpb" package can be used to // create Go type descriptors from protobuf descriptors. // -// -// Value Interfaces +// # Value Interfaces // // The Enum and Message interfaces provide a reflective view over an // enum or message instance. For enums, it provides the ability to retrieve @@ -55,13 +52,11 @@ // The "github.com/golang/protobuf/proto".MessageReflect function can be used // to obtain a reflective view on older messages. // -// -// Relationships +// # Relationships // // The following diagrams demonstrate the relationships between // various types declared in this package. // -// // ┌───────────────────────────────────┐ // V │ // ┌────────────── New(n) ─────────────┐ │ @@ -83,7 +78,6 @@ // // • An Enum is a concrete enum instance. Generated enums implement Enum. // -// // ┌──────────────── New() ─────────────────┐ // │ │ // │ ┌─── Descriptor() ─────┐ │ ┌── Interface() ───┐ @@ -98,12 +92,22 @@ // // • A MessageType describes a concrete Go message type. // It has a MessageDescriptor and can construct a Message instance. +// Just as how Go's reflect.Type is a reflective description of a Go type, +// a MessageType is a reflective description of a Go type for a protobuf message. // // • A MessageDescriptor describes an abstract protobuf message type. +// It has no understanding of Go types. In order to construct a MessageType +// from just a MessageDescriptor, you can consider looking up the message type +// in the global registry using protoregistry.GlobalTypes.FindMessageByName +// or constructing a dynamic MessageType using dynamicpb.NewMessageType. // -// • A Message is a concrete message instance. Generated messages implement -// ProtoMessage, which can convert to/from a Message. -// +// • A Message is a reflective view over a concrete message instance. +// Generated messages implement ProtoMessage, which can convert to a Message. +// Just as how Go's reflect.Value is a reflective view over a Go value, +// a Message is a reflective view over a concrete protobuf message instance. +// Using Go reflection as an analogy, the ProtoReflect method is similar to +// calling reflect.ValueOf, and the Message.Interface method is similar to +// calling reflect.Value.Interface. // // ┌── TypeDescriptor() ──┐ ┌───── Descriptor() ─────┐ // │ V │ V diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go index 121ba3a07..0b9942885 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/source.go @@ -87,6 +87,7 @@ func (p1 SourcePath) Equal(p2 SourcePath) bool { // in a future version of this module. // // Example output: +// // .message_type[6].nested_type[15].field[3] func (p SourcePath) String() string { b := p.appendFileDescriptorProto(nil) diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go index 8e53c44a9..3867470d3 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/type.go @@ -480,6 +480,7 @@ type ExtensionDescriptors interface { // relative to the parent that it is declared within. // // For example: +// // syntax = "proto2"; // package example; // message FooMessage { diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go index eb7764c30..ca8e28c5b 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go @@ -50,6 +50,7 @@ import ( // always references the source object. // // For example: +// // // Append a 0 to a "repeated int32" field. // // Since the Value returned by Mutable is guaranteed to alias // // the source message, modifying the Value modifies the message. @@ -392,6 +393,7 @@ func (v Value) MapKey() MapKey { // ╚═════════╧═════════════════════════════════════╝ // // A MapKey is constructed and accessed through a Value: +// // k := ValueOf("hash").MapKey() // convert string to MapKey // s := k.String() // convert MapKey to string // diff --git a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go index 59f024c44..58352a697 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go +++ b/vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go @@ -30,9 +30,11 @@ import ( // conflictPolicy configures the policy for handling registration conflicts. // // It can be over-written at compile time with a linker-initialized variable: +// // go build -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn" // // It can be over-written at program execution with an environment variable: +// // GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main // // Neither of the above are covered by the compatibility promise and diff --git a/vendor/google.golang.org/protobuf/runtime/protoimpl/version.go b/vendor/google.golang.org/protobuf/runtime/protoimpl/version.go index ff094e1ba..a105cb23e 100644 --- a/vendor/google.golang.org/protobuf/runtime/protoimpl/version.go +++ b/vendor/google.golang.org/protobuf/runtime/protoimpl/version.go @@ -26,16 +26,19 @@ const ( // EnforceVersion is used by code generated by protoc-gen-go // to statically enforce minimum and maximum versions of this package. // A compilation failure implies either that: -// * the runtime package is too old and needs to be updated OR -// * the generated code is too old and needs to be regenerated. +// - the runtime package is too old and needs to be updated OR +// - the generated code is too old and needs to be regenerated. // // The runtime package can be upgraded by running: +// // go get google.golang.org/protobuf // // The generated code can be regenerated by running: +// // protoc --go_out=${PROTOC_GEN_GO_ARGS} ${PROTO_FILES} // // Example usage by generated code: +// // const ( // // Verify that this generated code is sufficiently up-to-date. // _ = protoimpl.EnforceVersion(genVersion - protoimpl.MinVersion) @@ -49,6 +52,7 @@ const ( type EnforceVersion uint // This enforces the following invariant: +// // MinVersion ≤ GenVersion ≤ MaxVersion const ( _ = EnforceVersion(GenVersion - MinVersion)